可以通过javascript访问Django CSRF cookie吗?

时间:2013-07-30 21:56:05

标签: 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. ...

然后,它还声明可以通过javascript:

从cookie获取csrf令牌
var csrftoken = $.cookie('csrftoken');

这两个陈述不冲突吗?假设存在Cross Origin攻击,然后攻击者可以从cookie获取CSRF令牌,然后在头部中使用CSRF令牌发出POST请求?有人可以解释一下吗?

更新

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

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

2 个答案:

答案 0 :(得分:2)

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

  

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

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

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

足够清楚?

答案 1 :(得分:2)

我相信this post会回答您更新的问题:

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

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

以下是OWASP的引用:

  

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

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

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

我不是专家,但这是我对问题的理解。希望它有所帮助。