Django 内置的 CSRF 保护够用吗?

信息安全 xss csrf
2021-08-13 16:07:12

Django 通过 cookie 在用户机器上设置一个 CSRF 保护令牌。然后它会在 POST 请求中请求令牌。如果这两个不匹配,则返回 403。

如果我手动更改了我在请求中发送的 cookie 和令牌值,则请求被接受。Django 不验证令牌值是否由服务器设置。只要 cookie 和请求匹配,它就不会返回 403。

这似乎并不安全。如果另一个网站欺骗了我的域并设置了新的 cookie,然后在请求中发送新 cookie 的 CSRF 令牌值怎么办?Django 将比较两者并认为请求合法。
他们是否有任何以不同方式实现这一点的软件包,或者我错过了什么?

2个回答

Django 正在使用Double-Submit Cookie,它被认为是一种安全的 CSRF 预防方法。为什么?因为,攻击者无法控制 CSRF 攻击中提交的 cookie CSRF 攻击依赖于浏览器管理 cookie 的事实,并将与目标域关联的 cookie 包含到伪造的 HTTP 请求中。使用 XSS 可以读取和修改非 HTTPOnly cookie,但是,几乎所有 Anti-CSRF 措施都可能被 XSS 破坏。

回答您的问题:
是的,只要应用程序不易受到 XSS 的攻击,Django 的 CSRF 保护系统将阻止 CSRF 攻击成功。

Django 的 CSRF 保护本身并没有被破坏;对于许多应用程序,它通常被认为是足够的。

但实际上,“双重提交 cookie”模型意味着如果攻击者可以在用户的​​浏览器上植入 cookie,CSRF 保护将失败:攻击者可以设置 cookie,然后立即在其令牌字段中提交具有相同值的表单. 这意味着存在从 cookie 强制到 CSRF 的潜在升级路线,这对于更安全的关键应用程序来说是不可接受的。

Cookie 强制本身通常不是简单的攻击。同源策略通常应该防止攻击者站点在另一个站点上设置 cookie。如果目标站点有 XSS 缺陷,那么显然你可以设置/获取 cookie,但是如果你有 XSS,那么你已经输得很惨,没有必要担心 CSRF。

作为应用程序作者,托管因素可能超出您的控制范围:

  1. 当您的站点使用 HTTPS 并且攻击者对用户进行中间人攻击时。虽然他们无法欺骗您的 HTTPS 网站,但他们可以将用户定向到同一主机名上的 HTTP 地址,并从那里写入一个 cookie,稍后浏览器将发送该 cookie 到您的 HTTPS 站点。(使用Strict-Transport-Security标头可以在一定程度上缓解这种情况。)

  2. 如果您的网站上a.example.com,有另一个应用程序上运行的b.example.com是易受XSS,该应用程序可能会被滥用来设置所有的饼干example.com,这将随后由浏览器在发送到您的应用程序a.example.com

这是 cookie 的一个设计缺陷,应用程序无法判断 cookie 是否最初设置了匹配domainsecure属性,并且如果两个同名 cookie 设置为不同domain/secure结果本质上是未定义的。

“同步器令牌”和“加密令牌”(HMAC) 方法包括攻击者未知的服务器端机密,可防止从 cookie 强制升级到 CSRF。

不幸的是,Django 不适合共享功能的干净替换。在不破坏所有依赖它的应用程序的情况下改进或替换 CSRF 机制涉及到一堆丑陋的猴子补丁。