关于安全性:为网站实现“记住我”的最佳方式是什么?

What is the best way to implement “remember me” for a website?

我希望我的网站有一个用户可以点击的复选框,这样他们就不必每次访问我的网站都登录。我知道我需要在他们的计算机上存储一个cookie来实现这一点,但是cookie中应该包含什么?

此外,是否有一些常见的错误需要注意,以防止此cookie出现安全漏洞,这在仍然提供"记住我"功能的情况下是可以避免的?


改进的持久登录cookie最佳实践

您可以使用此处描述的最佳实践(2006年)或此处描述的更新策略(2015年):

  • 当用户成功登录并选中了RememberMe时,除了标准会话管理cookie外,还会发出一个登录cookie。
  • 登录cookie包含一个序列标识符和一个令牌。序列和标记是来自适当大空间的不可测随机数。两者都存储在一个数据库表中,标记被散列(sha256很好)。
  • 当非登录用户访问站点并显示登录cookie时,将在数据库中查找序列标识符。
  • 如果序列标识符存在,并且令牌的散列与该序列标识符的散列匹配,则认为用户已通过身份验证。生成新的令牌,在旧记录上存储令牌的新哈希,并向用户发出新的登录cookie(可以重新使用序列标识符)。
  • 如果序列存在但令牌不匹配,则假定为盗窃。用户将收到一个措辞强烈的警告,并删除用户记住的所有会话。
  • 如果用户名和序列不存在,则忽略登录cookie。
  • 这种方法提供了深度防御。如果有人设法泄漏了数据库表,它不会为攻击者提供一扇模拟用户的大门。


    我会存储一个用户ID和一个令牌。当用户返回站点时,将这两条信息与持久性的信息(如数据库条目)进行比较。

    至于安全性,不要把任何东西放在里面,让别人修改cookie以获得额外的好处。例如,不要存储他们的用户组或密码。任何可以被修改的规避安全的东西都不应该存储在cookie中。


    存储他们的用户名和一个remembertoken。当他们登录"记住我"复选框时,生成一个新的"记住我"(它使标记为"记住我"的任何其他机器失效)。

    当他们返回时,通过rememberMe令牌查找它们,并确保用户ID匹配。


    我亲自调查了持续的会话,发现这根本不值得承担安全风险。如果必须使用它,那么可以使用它,但是您应该只考虑这样一个会话的弱身份验证,并强制对攻击者有价值的任何内容进行新的登录。

    当然,原因是包含持久会话的cookie很容易被盗。

    4种偷你饼干的方法(摘自Jens Roland在@splattne页上的评论,他的答案基于此):

  • 通过不安全线路拦截(包嗅探/会话劫持)
  • 直接访问用户的浏览器(通过恶意软件或物理访问框)
  • 从服务器数据库中读取(可能是SQL注入,但可能是任何东西)
  • 通过XSS黑客(或类似的客户端攻击)