为什么双重提交 Cookie 需要单独的 Cookie?

信息安全 csrf
2021-09-07 20:32:26

根据https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Double_Submit_Cookies

当用户对站点进行身份验证时,该站点应该生成一个(加密性强的)伪随机值,并将其设置为用户机器上的 cookie ,与会话 id 分开

(强调我的)

如果会话 id 是,为什么 CSRF 令牌需要存储在单独的 cookie 中:

  • 随机值(攻击者无法猜测的值)
  • 存储在 cookie 中(攻击者无法读取的值)
  • 由服务器生成(攻击者无法写入的值)

为什么不简单地使用会话 ID 作为 CSRF 令牌?您仍然需要提交两次值(一次在 cookie 中,一次在表单中)并比较值,但不会为 CSRF 令牌使用单独的 cookie。

2个回答

原因是这允许标记主会话 cookie HttpOnly(因此 Javascript 无法访问它)。关于这增加了多少价值存在一些争论HttpOnly,但似乎使某些类型的攻击更加困难,因此可以说是一种有用的强化措施。

如果您没有使用单独的 cookie,而只是将会话 ID 重新用于这些目的,那么 Javascript 将需要读取会话 cookie 的能力,而我们将无法标记会话 cookie HttpOnly通过使用单独的值,可以标记会话 cookie HttpOnly

这就是为什么他们建议使用单独的值。

我能想到的原因有几个:

  • 如果 CSRF 令牌泄露,它不会泄露身份验证 cookie。
  • 它允许您将身份验证令牌设置为仅 HTTP,并且仍然具有可由 JavaScript 读取以构建 AJAX 请求的 CSRF 值

就个人而言,我不认为双重提交 cookie 技术非常有效。虽然它不是一般的 CSRF,但如果我可以 MITM 用户的纯文本流量,那么我可以针对仅限 https 的站点执行 CSRF。这是通过注入一个 iframe 或 img 与受攻击站点的来源,然后用我自己的 CSRF cookie 响应 iframe 或 img,最后通过生成跨站点请求来完成的。(是的,它需要用户的 MITM,但允许对仅在没有 HSTS 的情况下通过 SSL 提供服务的站点执行明文 MITM 攻击。正如 Gili 指出的那样,使用 HSTS 可以减轻这种攻击。)