javascript可以访问Django CSRF cookie吗?

Kev*_*ang 5 django django-csrf

在 django 网站上,https : //docs.djangoproject.com/en/dev/ref/contrib/csrf/它指出:

The CSRF protection is based on the following things:

1. A CSRF cookie that is set to a random value (a session independent nonce, as it is called), which other sites will not have access to.
2. ...
Run Code Online (Sandbox Code Playgroud)

然后,它还说明可以通过 javascript 从 cookie 中获取 csrf 令牌:

var csrftoken = $.cookie('csrftoken');
Run Code Online (Sandbox Code Playgroud)

这两个说法不矛盾吗?假设有一个跨域攻击,那么攻击者可以从cookie中获取CSRF令牌,然后在标头中使用CSRF令牌进行POST请求?有人可以解释一下吗?

更新

我现在意识到,只有来自同一来源的 javascript 才被允许访问 cookie。一个后续问题是:

如果 POST 请求自动将 cookie 作为请求的一部分添加,并且 django 的 csrf cookie 值与 csrf 令牌相同,那么恶意跨源请求仍然具有正确的 CSRF 令牌?(在饼干中)

Jon*_*rin 2

我相信这篇文章回答了您更新的问题:

由于同源策略的原因,攻击者确实无法访问到cookie。但正如您提到的,浏览器无论如何都会将 cookie 添加到 POST 请求中。因此,还必须从代码中发布 CSRF 令牌(例如,在隐藏字段中)。在这种情况下,攻击者必须知道受害者创建恶意表单时存储在受害者 cookie 中的 CSRF 令牌的值。由于她无法访问 cookie,因此她无法在恶意代码中复制令牌,攻击就会失败。

现在,人们可能会想到除 cookie 之外的其他存储令牌的方式。关键是攻击者一定不能得到它。并且服务器必须有一种方法来验证它。您可以想象将令牌与会话一起保存在服务器端,并在客户端以某种“安全”方式存储令牌(“安全”意味着攻击者无法访问它)。

以下是 OWASP 的引用:

一般来说,开发人员只需为当前会话生成一次此令牌。初始生成此令牌后,该值将存储在会话中,并用于每个后续请求,直到会话过期。当最终用户发出请求时,服务器端组件必须与会话中找到的令牌相比,验证请求中令牌的存在性和有效性。如果在请求中未找到令牌或提供的值与会话中的值不匹配,则应中止请求,应重置令牌,并将事件记录为正在进行的潜在 CSRF 攻击。

最后,安全性需要两件事:

  • CSRF 令牌必须从代码中发送,这意味着恶意代码必须知道它。
  • CSRF 令牌必须存储在某个“安全”的地方以进行比较(cookie 对此很方便)。

我不是专家,但这是我对这个问题的理解。希望能帮助到你。