Django 如何验证 CSRF?

How Django verifies CSRF?

根据我的理解,Django 验证 CSRF 的方式是通过比较

request.POST.get('csrfmiddlewaretoken', '') | request.META.get(settings.CSRF_HEADER_NAME, '') == request.session.get(CSRF_SESSION_KEY) | request.COOKIES[settings.CSRF_COOKIE_NAME]

CsrfViewMiddleware

现在,这 2 个标记(一个来自 LHS,一个来自 RHS)通过使用以下函数进行解密进行比较

_unsalt_cipher_token

正在比较的 2 个标记不同,但被解密为相同的 "secret"

我的问题是 Django 不应该确保它们不同吗?如果不能确保它们不同,使用 2 个不同令牌(以及解密它们的开销)的目的是什么?

我不是安全专家,但 documentation 声明

In order to protect against BREACH attacks, the token is not simply the secret; a random salt is prepended to the secret and used to scramble it.

您可以在 wikipedia 上阅读有关 BREACH 的更多信息。

在每个请求中泄露未加盐的 CSRF 秘密会使服务器暴露于 BREACH 攻击,因此 Django 提供加盐的秘密,当它收到 CSRF 令牌时,它会解开它并将其与秘密进行比较以检查它们是否匹配。

我觉得提问者的疑点不多

  1. 为什么在cookie中设置token

    这在 jd.'s and Mike DeSimone's 个答案中有解释。

    简而言之支持AJAX发布并避免任何服务器端状态存储

  2. 代币为什么要加盐? 这在

    总之防止BREACH攻击

  3. 为什么我们不能在表单和 cookie 中使用单一的加盐标记?

    我认为那是因为如果我们使用相同的加盐令牌,那么我们需要在服务器端存储秘密(未加盐令牌)。