5

在 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. ...

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

var csrftoken = $.cookie('csrftoken');

这两种说法不矛盾吗?假设有Cross Origin攻击,那么攻击者可以从cookie中获取CSRF token,然后在header中使用CSRF token进行POST请求?有人可以解释一下吗?

更新

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

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

4

2 回答 2

2

I believe that this post answers your updated question:

Because of the same-origin policy, the attacker cannot access the cookie indeed. But the browser will add the cookie to the POST request anyway, as you mentioned. For this reason, one must post the CSRF token from the code as well (e.g. in a hidden field). In this case, the attacker must know the value of the CSRF token as stored in the victim's cookie at the time she creates the malicious form. Since she cannot access the cookie, then she cannot replicate the token in her malicious code, and the attack fails.

Now, one might imagine other ways of storing the token than in the cookie. The point is that the attacker must not be able to get it. And the server must have a way to verify it. You could imagine saving the token together with the session on the server-side, and storing the token in some "safe" way on the client side ("safe" meaning that the attacker cannot access it).

Here is a quote from OWASP:

In general, developers need only generate this token once for the current session. After initial generation of this token, the value is stored in the session and is utilized for each subsequent request until the session expires. When a request is issued by the end-user, the server-side component must verify the existence and validity of the token in the request as compared to the token found in the session. If the token was not found within the request or the value provided does not match the value within the session, then the request should be aborted, token should be reset and the event logged as a potential CSRF attack in progress.

In the end, the security needs two things:

  • The CSRF token must be sent from the code, which means that the malicious code must know it.
  • The CSRF token must be stored in some "safe" place for comparison (the cookie is convenient for this).

I am not a specialist, but this is my understanding of the problem. Hope it helps.

于 2014-05-23T05:24:47.817 回答
2

从名称 CSRF(Cross Site Request Forgery)中,您已经可以猜到攻击者必须执行来自“跨站点”(其他站点)的请求。

“理解 CSRF 攻击的关键是要认识到网站通常不会验证请求是否来自授权用户。相反,它们只验证请求来自授权用户的浏览器。” -在这里引用

所以对于不能阻止 CSRF 攻击的网站,攻击者可以从任何地方发送恶意请求:浏览器、电子邮件、终端……由于网站没有检查请求的来源,它认为是授权用户发出了要求。

在这种情况下,在每个 Django 表单中,您都有一个隐藏的输入,称为“CSRF 令牌”。该值是在表单呈现时随机且唯一地生成的,并将在发出请求后进行比较。所以请求只能从授权用户的浏览器发送。攻击者无法(据我所知)获取此令牌并执行 Django 后端可以接受的恶意请求。

够清楚吗?

于 2013-07-30T22:29:20.033 回答