【问题标题】:How Django verifies CSRF?Django 如何验证 CSRF?
【发布时间】:2018-09-15 14:13:05
【问题描述】:

据我了解,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

现在,比较这两个令牌(一个来自 LHS,一个来自 RHS)的方式是通过使用以下函数进行解密

_unsalt_cipher_token

被比较的 2 个令牌不同,但被解密为相同的 “秘密”

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

【问题讨论】:

  • 为什么要检查它们是否不同?
  • 为什么他们首先要制作两个不同的令牌?不管是什么原因,他们不应该确保它是不同的吗?
  • 我真的完全无法理解你的想法。 为什么它们应该不同?重点是避免请求伪造,即确保 POST 是对先前发送的 GET 的响应。那么,这会让您觉得他们需要有所不同吗?
  • 我理解 CSRF 的目的,我认为它不应该有所不同。但它是。我试图理解为什么?

标签: python django csrf csrf-protection django-csrf


【解决方案1】:

我认为提问者有几个不同的疑问

  1. 为什么在cookie中设置token

    这在jd.'sMike DeSimone's 的答案中有解释。

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

  2. 令牌为什么要加盐? 这在 Jacques Gaudin's answer

    总之防止BREACH攻击

  3. 为什么我们不能在表单和 cookie 中都使用一个加盐令牌?

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

【讨论】:

    【解决方案2】:

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

    为了防止BREACH攻击,令牌不仅仅是秘密;一个随机盐被添加到秘密中并用于对其进行加扰。

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

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

    【讨论】:

    • 我明白为什么 Django 会发送一个加盐的秘密,我不明白的是,如果两个令牌(加盐的秘密)相同,它为什么不拒绝请求。
    • 对不起,我不明白你的问题。
    • 表单和 cookie 中的 CSRF(都是加盐的)是不同的字符串,对吧?那是为了防止BREACH攻击。但是如果你从 cookie 中取出 csrf 并用它来替换隐藏的 csrf 输入字段,它仍然可以工作。为什么 Django 不保证这 2 个 csrf 不同?
    • 否表单和cookie中的CSRF是一样的。要验证 ajax 帖子,您需要从 cookie 中获取 crsftoken。
    • 你确定表单和cookie中的CSRF是一样的吗?它不适合我。此外,我查看了 Django 代码及其验证表单中的 CSRF 与 cookie 中的 CSRF。因此,从 cookie 中获取 CSRF 就达不到目的了。
    猜你喜欢
    • 2016-03-03
    • 2011-09-28
    • 2013-05-03
    • 2012-09-08
    • 2015-06-02
    • 1970-01-01
    相关资源
    最近更新 更多