【问题标题】:PHP "Remember Me" security flaw?PHP“记住我”安全漏洞?
【发布时间】:2012-12-17 08:12:17
【问题描述】:

我正在编写一个配备“记住我”的登录表单,到目前为止,我阅读的教程(部分是为了确保我做对了)都说要将加密的密码存储在cookie 和用户名。然后,每次 PHP 检查当前用户是否未登录时,检查他们的 cookie 并查找这些值。如果用户名与密码匹配,您就进入了。

对我来说,这是一个巨大的安全漏洞。如果有人要破解数据库或以某种方式访问​​加密密码,他们甚至不需要破解它们。只需设置您自己的 cookie 即可。我是正确的,还是只是偏执?

我的登录系统使用会话来跟踪当前用户 ID,并使用 1/0 进行快速登录/注销检查。用户无法编辑会话 AFAIK,因此这是安全的(如果不是,请告诉我)。我正在考虑将会话 ID 存储在 cookie 中,以便稍后恢复它,但这也不安全。

我非常关心我的用户的安全,如何在保持网站正常运行的同时妥善保护他们的信息?

【问题讨论】:

  • 我不会存储加密密码,只是将 user_ID 存储在 X 天后过期的 cookie 中。对于“敏感”区域(例如帐户/个人资料管理),如果他们没有有效的 $_SESSION(您应该在他们登录时设置),您可以要求他们登录。
  • 如果将会话 ID 存储在 cookie 中“不安全”,您当前如何存储它?
  • @georgefox 目前,我没有将会话 ID 存储在任何东西中,我只是说记住我功能的可能性。
  • 理论和想法:我只是将会话的 cookie 过期时间设置为默认时间,然后如果用户选中“记住我”选项,则使调用用户会话的 cookie 持续存在更长。
  • @Jaxo,为了让您的会话正常工作,客户必须不断向您发送他或她的会话 ID。这几乎总是通过在 cookie 中设置会话 ID(例如 PHPSESSID)来完成,客户端将每个请求发送回您的域。这一切都由 PHP 在内部处理,并且可以在 php.ini 中进行配置。您可能没有明确地对会话 ID 做任何事情,但 PHP 正在为您将会话 ID 存储在 cookie 中。

标签: php security login remember-me


【解决方案1】:

通常当请求服务器记住用户时,它会在正常会话cookie之外发出一个额外的cookie,这个新字符串包含用户名和合理的数量随机字符,使其无法猜测。这显然保存在数据库中(出于安全原因,您可能希望将其视为密码,因此对其进行加盐和哈希处理),并且下次用户使用同一浏览器连接时(假设旧会话已过期),应用程序会收到随机字符串,检查数据库,如果匹配,则用户通过身份验证。

另一种方法是将会话到期时间提前一些时间。

这里有哪些安全漏洞?如果您使用好的随机生成器,唯一可能发生的情况是用户从共享浏览器访问应用程序,并且在结束时没有手动注销。

正常规则始终适用,因为您处于不安全的通道中:使用 HTTPS,否则位于您的计算机和服务器之间的任何人都可以窃取 cookie(会话之一或 remember -me one) 并表现得像你一样。

Bonus, this must-read by Jeff Atwood

【讨论】:

  • 这似乎是个好方法,谢谢!另外,现在阅读那个怪物登录帖子!
【解决方案2】:

切勿在客户端以任何方式保存密码(可用于登录的加密密码仍然是密码)。

使用随机生成的密钥,安全地存储在服务器上。这些密钥可以在以后撤销,而加密密码在更改之前一直有效。

使用 php,您可以生成像这样的随机密钥md5(uniqid(mt_rand(), true))。为了更好的安全存储,它在 db 中加盐和散列。

示例表:

login_keys (
  user_id int,
  key char(40), # sha1
  salt char(15)
)

还请注意,您应该启用 HTTP only cookie 选项。

【讨论】:

    【解决方案3】:

    如果您希望它安全,请不要让您的用户保持登录状态。

    在设置会话的时候,一定要把ipaddress绑定到会话ID上,这样以后如果有人接了会话,就只能从同一个IP地址来做。 你可以通过使用(散列)会话 ID + 散列 IP 地址来保存数据库来做到这一点。 我使用 phps 函数 http://php.net/manual/en/class.sessionhandler.php 设置会话处理程序并将会话与 ipaddresses 匹配。

    【讨论】:

    • IP 地址不用于安全,您不能信任 IP 地址。正如您所指出的,IP 检查仍然使坏人的生活更加艰难。
    【解决方案4】:

    我在自己的网站上工作时遇到了同样的问题,我发现解决这个问题的最佳方法是根本不记住密码,只记住用户名,提供更快的登录,但不会降低安全性。事实是,没有可靠的方法来保证密码的绝对安全。除了使用新的浏览器,用户还可以让他们的浏览器记住它。

    但如果您必须保存密码,请尝试以下操作:

    拥有多个 cookie,其中 2 个是最简单的,其中一个用于加密密码,另一个用于保存加密密钥。数据库中的密码将包含一个进一步加密的密码,通过使用您存储的加密密钥获得。当您准备好检查密码时,提取值并加密密码。

    希望这对您有所帮助。祝你好运!

    编辑:我可能误解了这一点,如果用户仍然登录,最好存储会话变量。

    【讨论】:

    • 永远不要在客户端以任何方式保存密码(可用于登录的加密密码仍然是密码)。仅保存存储在服务器上的密钥。这些密钥可以稍后撤销,但加密的密码在更改之前一直有效。
    • 这不一定是真的,因为人们会设置一个到期日期;但是,我宁愿不使用第二种方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多