将某人登录到网站的最安全方法是什么?

时间:2015-05-29 17:25:42

标签: php security token remember-me login-control

我正在尝试确定在我验证登录正确后让某人登录我的网站的最佳方法。

我试着看看"Keep Me Logged In" - the best approach,其中最受欢迎的答案说我应该生成一个令牌,然后将此令牌存储在数据库中!当然这完全是不安全的,因为所有需要的是数据库黑客和cookie编辑才能进入别人的账户?

有人可以向我提供目前最新的安全方式吗?感谢。

2 个答案:

答案 0 :(得分:4)

我们最近发布了一篇关于secure authentication with long-term persistence(又名“记住我”)的博客,但此博客帖子与ircmaxell's answer to "Keep Me Logged In" - the best approach之间的最大区别是查找的分离(不是{{3} })和验证(这是恒定时间)。

在我们博客文章中概述的策略中,您没有在数据库中存储令牌,而是存储令牌的SHA-256哈希值。如果攻击者泄露了这些值,他必须破解SHA-256哈希的强随机令牌。他们最好只启动一个反向shell,让他们可以像任何用户一样进行身份验证(或者继续使用本地内核利用来接管整个机器)。

登录(简单和基本)

  • 使用bcrypt。具体为password_verify()不要生成自己的盐。

    如果您想加倍努力,请考虑使用此constant-time库来加密密码哈希值(如果您将数据库和网络服务器放在不同的硬件上,这将非常有用,因为妥协数据库不会给他们加密密钥)。

  • 限价失败尝试。例如:每个IP或用户名失败5次后,需要验证码。

长期持久性(“记住我”)

登录时:

  1. 生成安全随机令牌。
  2. 生成安全的随机标识符。
  3. 将标识符和令牌存储在rememberme Cookie中。
  4. 将令牌的SHA256哈希值存储在数据库中。
  5. 当用户登陆页面时,如果他们有rememberme cookie,请抓取标识符并进行数据库搜索。
  6. 如果此标识符有身份验证令牌,请抓取SHA256哈希值。
  7. 使用hash_equals()将Cookie提供的令牌的哈希值与数据库中的SHA256哈希值进行比较。
  8. 如果成功,请将会话变量设置为该用户的ID。生成新令牌。如果失败,请从数据库中删除该条目。
  9. 本策略的优点

    • 如果成功的SQL注入攻击导致令牌被泄露,则攻击者所拥有的是各种令牌的SHA256哈希值。这对妥协帐户没有帮助。
    • 数据库搜索不是bcrypt + AES。这就是标识符与令牌分离的原因。
    • 顺序标识符泄露了您的应用程序的活动级别,许多企业希望保密。随机标识符模糊了这个细节。

    缺点

    • (未来的StackOverflow作者如果发现任何内容,应随意填充此列表。)

答案 1 :(得分:1)

以明文形式将生成的令牌存储在数据库中显然是一种风险,但通常被认为是可接受的。一种缓解技术是要求用户在执行敏感操作之前重新进行身份验证。例如,在我修改帐户详细信息之前,亚马逊似乎要求我输入密码,除非我最近输入了密码。