Django 允许您指定会话在浏览器关闭时过期(对 Chrome 有一些警告)。为什么它不对 CSRF cookie 这样做呢?
我问是因为在我看来 CSRF 令牌很容易被泄露(例如,错误地将其放在外部站点的帖子中),这将是一种缓解措施。我是不是误会了什么?
我将从 Carl 链接的开发人员列表中重新发布我的答案,以便 stackoverflow 也有它:
如果 cookie 设置为在浏览器关闭时过期,则会导致关闭浏览器(或将带有表单的页面添加为书签)然后从浏览器缓存加载该页面并提交表单的用户出现 CSRF 错误。我对这个用例是否值得支持感到矛盾(例如,它在移动设备上可能很重要),但我不认为将 cookie 设置为在浏览器关闭时过期会给其他正确配置的站点带来很多安全优势(HTTPS、HSTS 等)。
Django 的 CSRF 实现 [1] 与许多其他实现不同,后者将 CSRF 信息与会话信息一起存储在服务器上。CSRF 机制通过将表单中提供的令牌与浏览器中作为 cookie 提供的令牌进行匹配来发挥作用。如果您将 cookie 设置为“zzz”,它仍然可以正常运行。安全性来自攻击者无法设置 cookie 的事实,而不是它恰好包含任何特定的加密值。
如果担心攻击者可以在会话之间访问用户的物理计算机并窃取 CSRF 令牌,则将其设置为在浏览器关闭时过期不会阻止攻击者插入将在下一个会话期间使用的已知值的 cookie。我不相信我们可以保护其计算机已被攻击者物理访问的用户的令牌。
尽管如此,如果可以令人信服地证明将 cookie 设置为在浏览器关闭时过期不会破坏现有的用例(移动浏览器是我的主要关注点),我愿意改变默认行为。如果任何非恶意用户可以通过无辜行为触发 CSRF 警告,我们通常认为这是一个错误。
[1] Django 的 CSRF 实现通常会在大多数渗透测试工具中引发各种错误警报,因为它的工作方式与其他实现不完全相同,并且与会话 cookie 无关。
这个问题之前已在 django-developers 邮件列表中提出并回答。