为什么不将密码存储在 cookie 中?

信息安全 验证 密码 饼干 客户端 理论
2021-09-10 08:39:12

我有一个新手问题-

人们常说,您不应该将明文密码存储 客户端 cookie 中。(我在想象一个网络浏览器 cookie,但我认为这通常适用。)但在简单的网络应用程序中,我们经常将纯文本会话 ID 存储在 cookie 中。

详细地说,我们经常使用这种模型来保护网站:

  1. 用户在客户端机器上输入用户名和密码。这些通过安全 (HTTPS) 连接发送到服务器。
  2. 服务器对密码进行哈希处理并针对数据库进行验证。假设密码正确,服务器会生成一个会话 ID,并将其与响应正文一起返回给客户端机器。
  3. 客户端将明文会话 ID 存储在 cookie 中。每次客户端再次调用服务器时,会话 ID 都会通过安全连接发送回服务器。
  4. 在 x 分钟不活动后,会话过期并且会话 ID 不再被视为对该用户有效。

但是我们强烈建议不要使用这个模型:

  1. 用户在客户端机器上输入用户名和密码。这些以纯文本形式存储在客户端 cookie 中。然后,它们通过安全 (HTTPS) 连接发送到服务器。
  2. 服务器对密码进行哈希处理并针对数据库进行验证。假设密码正确,服务器返回响应。
  3. 每次客户端再次调用服务器时,密码都会通过安全连接发送回服务器。
  4. 在 x 分钟不活动后,cookie 过期并且密码不再保存在客户端计算机上。

为什么第二个模型被认为是不安全的,而第一个模型是安全的?当然,在第二种模型中,一个邪恶的 cookie 阅读器可以从浏览器中窃取密码。但在这两种模型中,邪恶的密钥阅读器都可以从 IO 子系统中窃取密码。这是不使用第二个模型的唯一原因 - 通过阻止 cookie 读取器来稍微减少我们的攻击向量?或者在客户端上存储密码是否存在更大的问题,我没有看到?

2个回答

反对第二种模式的几点:

  • 散列密码应该花费大量时间,以便在数据库泄漏的情况下减缓暴力破解。检查每个请求的密码是一种资源浪费。
  • Cookie 可能容易受到 XSS 攻击,并且密码被盗比会话被盗更糟糕(密码不会经常更改,而且它们往往会在多个站点上重复使用)。
  • Cookie 通常未加密地存储在客户端上。
  • 会话不能轻易失效,因为它需要更改密码。
  • 它与任何单点登录系统完全不兼容(感谢@CBHacking)

存储密码哈希而不是密码并没有好多少,您解决了性能问题,但您仍然可能会泄露密码哈希以被暴力破解,并且您不能轻易使会话无效,甚至无法将它们区分开来具有多个并发会话的用户的情况。

完全同意前面的回答。这里有更多的上下文来帮助您评估解决方案的安全性。

您的第一个模型几乎是使用 cookie 进行的典型会话管理。支持会话所需的所有主要用例。

您的第二个模型有点类似于Basic Auth,除了身份验证数据可以通过泄漏的 cookie 暴露给客户端(不设置 HTTPOnly 标志)。如果设置了 HTTPOnly 标志,则您非常接近基本身份验证,共享它的大部分属性:没有可靠的超时、缺少 SSO 支持、泄露密码、没有多个会话等。

我整理了一份Web 身份验证指南,以帮助确定哪些身份验证方案最适合您的用例。看看这个!