还记得我最好的Cookie吗?

时间:2011-08-27 12:12:47

标签: security cookies session-cookies

我读到了很多关于这个论点的旧问题,我认为最佳做法是设置一个包含usernameuser_id和随机令牌的Cookie。

同一个cookie的数据在创建cookie时存储在数据库中,当用户拥有cookie时,它们会被比较(cookie数据,数据库数据)。

真诚地,如果这是最佳实践,我无法理解安全逻辑在哪里。

窃取cookie的攻击者拥有与原始用户相同的cookie:|

忘了一步? :P

7 个答案:

答案 0 :(得分:52)

你永远不应该在cookie中存储用户密码,即使它已经散列!!

看一下这篇博文:

引用:

  
      
  1. 当用户成功登录并选中记住我时,除标准会话管理cookie外还会发出登录cookie。[2]
  2.   
  3. 登录cookie包含用户的用户名,系列标识符和令牌。系列和令牌是来自适当大空间的不可取的随机数。这三个都存储在一个数据库表中。
  4.   
  5. 当未登录的用户访问该站点并显示登录cookie时,将在数据库中查找用户名,系列和令牌。
  6.   
  7. 如果存在三元组,则认为用户已通过身份验证。使用的令牌将从数据库中删除。生成一个新令牌,使用用户名和相同的系列标识符存储在数据库中,并向用户发出包含所有三个的新登录cookie。
  8.   
  9. 如果存在用户名和系列但令牌不匹配,则假定盗窃。用户收到强烈警告的警告,并删除所有用户记住的会话。
  10.   
  11. 如果用户名和系列不存在,则忽略登录cookie。
  12.   

答案 1 :(得分:20)

除了用户密码之外,您应该存储user_id并发出随机令牌。使用cookie中的令牌并在密码更改时更改令牌。这样,如果用户更改了密码,则cookie将失效。

如果cookie被劫持,这很重要。如果用户检测到劫持,它将无效,此外,因为令牌与劫持者无法导出的密码无关,然后更改用户的帐户密码并“拥有”该帐户(假设您需要现有密码)在更改密码之前,劫持者不拥有电子邮件帐户,因此他们不能使用“忘记我的密码”等。)

注意令牌不易猜测(即它们应该由完全随机的数据组成,例如来自CRNG)。

如果您想更进一步,可以在发送之前对cookie进行加密,并在收到后对其进行解密。除此之外,不要假设劫持者不知道所使用的加密密钥,因此在解密时验证cookie的内容。

但是所有这一切,更喜欢使用库的持久会话管理,而不是自己动手。

答案 2 :(得分:4)

我甚至不会将用户名存储在Cookie中,只是使用near impossible to crack technique生成的随机令牌并将其映射到数据库中的用户,并且从不存储用户的密码在Cookie中哈希,它将向Brute Force Attack开放。是的,如果有人窃取了令牌,他可以访问用户的帐户,但密码不会受到损害,只要真实用户退出,令牌就会失效。另外请记住,您不应该允许敏感任务,例如将密码更改为只有有效令牌的用户,您需要再次请求密码才能执行此类任务。

答案 3 :(得分:3)

如果您的Cookie被盗,任何人都可以登录您的帐户。它实际上是firesheep的作用。安全性在于随机令牌。整个系统假定cookie不能被盗。进入的另一种方法是猜测随机令牌。如果你做得足够长,它应该几乎不可能。

答案 4 :(得分:0)

您似乎忘记的“步骤”是,如果cookie值被正确地散列,那么攻击者就会有一点价值。

编辑:

您可以采取以下措施保护用户免受与Cookie相关的攻击:

  • 随着时间的推移重新生成令牌,以便攻击者无法冒充用户,除非她有最近的cookie。如果安全性是最高优先级,则在每个请求(页面加载)上重新生成令牌。如果不是,请在密码更改时重新生成令牌。
  • 保留并验证user agents的哈希值,以便攻击者无法模拟用户,除非她同时拥有用户的cookie和用户代理。

P.S。 Cookie应该包含(随机)令牌而不是密码哈希(请参阅Hashes or tokens for "remember me" cookies?)。

答案 5 :(得分:-1)

我一直都知道“记住我”功能只会将会话cookie(即具有会话ID的cookie)从关闭浏览器到期日期到期时转换,它不涉及保存其他数据,只是扩展了会话。

是的,如果攻击者获得了cookie,它可以冒充用户。但这总是有效的,与“记住我”毫无关系。

答案 6 :(得分:-1)

我的方法如下:

  1. 哈希user_id
  2. 为用户生成唯一键 - md5(current_timestamp)
  3. 将密钥保存到数据库
  4. 对所有内容进行编码,使其看起来像BS-base64
  5. 将其保存在Cookie中
  6. 到目前为止,它一直很适合我:)