我想知道Cookie登录的最安全方式是什么?
如果您仅将通行证(用salt加密)和用户名存储在cookie中
并针对用户表进行验证,潜在的攻击者可以窃取Cookie并登录。
人们通常不会在"最后一次上网"时查看该信息。
那么"记住我的cookie"是否有更好的方法?
IP不是一个很好的选择,是吗? (某些机器一直在更改IP)。
请告诉我们有关您的应用程序将使用此功能的信息。 假冒/身份盗窃的潜在影响是什么?
大多数机器一直在更改IP ...
根据定义,"记住我"功能并不安全。 因此,取决于您在可用性和妄想之间进行选择。
那不是事实。我可以限制通过cookie登录时用户的选项(他必须在想要编辑详细信息等时重新验证),并且可以限制攻击者的窗口。
从技术上来说,"记住我"功能并不安全。 这可能是不安全的,因为用户与他人共享他们的设备,或者因为他们可能丢失了他们的设备。 您应该尽可能重用现有的身份验证框架,因为它确实很复杂。 例如,看看github.com/delight-im/PHP-Auth
我想我已经找到了一个聪明的解决方案!
此(复杂?)脚本的优点:
用户成功登录时
选中"记住我"并登录
除了
标准会话管理
Cookie。[2]
登录cookie包含用户的用户名,系列标识符和令牌。系列和令牌是来自适当大空间的不可猜测的随机数。所有这三个都一起存储在数据库表中。
当非登录用户访问网站并显示登录cookie时,将在数据库中查找用户名,系列和令牌。
如果存在三元组,则用户
被视为已认证。使用过的
令牌已从数据库中删除。一种
生成新令牌,并将其存储在
用户名和数据库
相同的系列标识符和一个新的
包含所有三个的登录cookie是
发布给用户。
如果用户名和系列是
存在但令牌不匹配,
假设是盗窃。用户收到
措辞强烈的警告以及所有
用户记住的会话是
已删除。
如果用户名和系列不是
目前,登录cookie被忽略。
我在数据库中制作了一个表,其中包含以下信息:
session | token | username | expire
记住我的cookie将具有以下设置:
$value ="$session|$token|$userhash"; //Total length = 106
Session将是40的字符串(sha1)
字符。
Token将是32的字符串(md5)
字符。
Cookie中的Userhash将是
字符串32(用户名md5)
字符。
数据库中的Username将是
普通用户名。
Expire将是+ 60天。
剧本:
if(isset($_SESSION['check']) || $_SESSION['check']){
//User is logged in
}else if(isset($_COOKIE['remember']) && strlen($_COOKIE['remember'])==106){
//THERE is a cookie, which is the right length 40session+32token+32user+2'|'
//Now lets go check it...
conncectdb(); //Sets connection
//How do I protect this script form harmful user input?
$plode = explode('|',$_COOKIE['remember']);
$session = mysql_real_escape_string($plode[0]);
$token = mysql_real_escape_string($plode[1]);
$userhash = mysql_real_escape_string($plode[2]);
$result = mysql_query(" SELECT user
FROM tokens
WHERE session = '$session'
AND token = '$token'
AND md5(user) = '$userhash';")
if(mysql_num_rows($result)==1){
//COOKIE is completely valid!
//Make a new cookie with the same session and another token.
$newusername = mysql_result($result,0,0);
$newsession = $session;
$newtoken = md5(uniqid(rand(), true));
$newuserhash = md5($username);
$value ="$newsession|$newtoken|$newuserhash";
$expire = time()+4184000;
setcookie('remember', $value, $expire, '/', 'www.example.com', isset($_SERVER["HTTPS"]), true);
mysql_query(" UPDATE tokens
SET token='$newtoken', expire='$expire'
WHERE session = '$session'
AND token = '$token'
AND md5(user)='$userhash';");
//Set-up the whole session (with user details from database) etc...
} else if(mysql_num_rows(mysql_query("SELECT user FROM tokens WHERE session = '$session' AND md5(user) = '$userhash';"))==1)){
//TOKEN is different, session is valid
//This user is probably under attack
//Put up a warning, and let the user re-validate (login)
//Remove the whole session (also the other sessions from this user?)
} else {
//Cookie expired in database? Unlikely...
//Invalid in what way?
}
} else {
//No cookie, rest of the script
}
该脚本的优点:
多次登录。您可以创建新的
您所使用的每台计算机上的会话。
Cookie和数据库将保持干净。
活跃用户每隔一个更新cookie
登录。
开始时的会话检查
确保数据库不会
得到无用的请求。
如果攻击者窃取了cookie,
得到一个新的令牌,但没有一个新的
会议。因此,当真正的用户访问时
旧网站(无效)
令牌但具有有效的用户会话
组合用户得到警告
潜在的盗窃行为。后
通过重新登录来重新验证
创建会话并创建会话
攻击者认为无效。的
重新验证确保受害者
确实是受害者,而不是
攻击者。
参考:http://jaspan.com/improved_persistent_login_cookie_best_practice
我看不到这种解决方案。此表中会话字段的目的是什么?为什么要专用桌子呢?为什么不只存储由某些用户数据组成的哈希?
任何其他解决方案都可以让您拥有多个会话,而无需其他表,而不会使脚本过于复杂
这限制了攻击者使用您的帐户的时间。
您甚至还读过剧本Col.?你已经在惩罚我= S
听起来很像这种技术:jaspan.com/improved_persistent_login_cookie_best_practice
它的确是我使用的=)但没有添加的是用户需要重新验证(以及实际代码)。该脚本中的缺陷在于,攻击者等到受害者获得新令牌后,才能通过尝试使用旧令牌进行身份验证来破坏其所有会话。
它写得很糟糕,但是正确,所以+1。
是什么使这不好?
我喜欢此验证方案中内置的隐式会话劫持检测。但是,实际上只有在有人使用"记住我"功能时才能检测到会话劫持。我想将其设置为可选,但我认为我仍然会使用与您在此处提出的建议类似的检测方法。
因此,您无需征得许可即可创建cookie?
这样的"记住我"功能始终会带来额外的安全风险。
因为就像在会话中一样,您仅具有一个标识符,该标识符不仅可以标识用户(它是谁?),还可以在不进行实际验证的情况下对该用户进行身份验证(真的是他/她吗?)。
但是,与会话(或应该拥有的)生命周期较短(通常少于一个小时)相反,并且(定期)更改标识符(或应该更改会话)(基于真实性/权威性状态更改的时间,以及必要性) ,"记住我"标识符的有效期为数天,即使数月或数年也无效!如此长的有效期带来了额外的安全风险。
因此,在询问如何实现这种"记住我"功能之前,您应该问自己是否真的想要这种额外的安全风险。这主要取决于您的应用程序拥有的资产,身份验证的目的以及是否要冒"记住我"功能构成的冒用身份/身份盗窃的风险。
如果是这样,请确保使用HTTPS提供基本的安全性,并在cookie中设置HTTPOnly标志和secure标志。然后,您可以执行以下操作来构建这样的"记住我"功能:
认证请求
如果用户通过HTTPS进行了身份验证并设置了"记住我"选项,则生成一个随机的"记住我"令牌,将其存储在服务器端的"记住我"数据库中,并使用带有该值的安全标志设置"记住我" cookie。然后开始新的会话并设置"记住我"标志。
任何其他要求
如果没有当前会话,请通过HTTPS重定向到"记住我"页面,该页面检查是否存在"记住我" cookie。如果有一个"记住我"令牌,则将其无效,使其无效,生成一个新令牌,将其存储在"记住我"数据库中,使用该新令牌设置一个cookie,并使用"记住我"标志设置一个新会话。否则,重定向到登录页面。
如果当前会话无效(请确保使用严格的会话无效),如果设置了"记住我"标志,则通过HTTPS重定向到"记住我"页面;否则,重定向到登录页面。
这样,可以通过HTTPS进行身份验证,包括初始身份验证和"记住我"身份验证。并且用户仅在当前会话期间是真实的;如果过期,则用户必须使用"记住我"令牌或提供他/她的登录凭据来重新进行身份验证。并且由于"记住我"令牌存储在数据库中,因此用户可以使任何现有的"记住我"令牌失效。
如果您真的想要额外的安全风险,我可以限制经cookie身份验证的用户以防止损坏。检查下面的脚本,您将永远不会获得幸运的随机令牌,因为如果令牌相同,则用户必须是两个相同。我想让我更永久地记住我,而不是仅仅将会话固定为更高的值。
这是一个答案,但是(对我而言)不是答案。
最受欢迎的方式:
许多脚本使用某种会话跟踪。当用户首次访问该网站时,它将为该用户生成一个唯一的随机ID,并将会话信息存储在服务器中,并将该ID存储在cookie中。然后,服务器使用唯一ID(称为会话ID)识别用户。与会话ID相关联的信息只能由服务器看到。 PHP默认使用它,
有些将用户数据存储在cookie本身中,但具有使用秘密字符串作为密钥的HMAC签名。如果签名不匹配,脚本将丢弃cookie。这样,服务器不必将会话数据保留在服务器上。用户通过查看cookie可以查看会话中的内容,因此您不应在其中存储敏感数据。仅用户ID(可能还有登录时间和cookie到期时间)就足够了。尽管用户可以看到会话信息中的内容,但Cookie中的签名可确保用户无法自己修改会话数据。
这些方式提供了一定的安全性,使用户无法篡改会话数据,但不能保护用户免遭窃听。他们始终可以使用数据包嗅探器并从任何开放的WiFi网络窃取会话。某些应用程序确实依赖于用户IP,但攻击者是否在同一网络中并不重要。某些应用程序依赖User-Agent,但是当用户更新其浏览器或从其他浏览器导入数据时会出现问题。
如果您真的担心安全性,请使用HTTPS。
另请阅读本文,尤其是"网站运营商如何解决问题"一节。
长文本,而不是一个话题。和不读但只有文字大小留下深刻印象的人的赞誉。
是不是有关登录Cookie及其安全性的主题?那就是我在回答中所说的。
它完全是主题,它为我提供了有关会话ID和HTTPS内容的更多想法。我没有投票。