Django自带了CSRF保护中间件 ,它生成一个唯一的每个会话令牌的形式使用。 它会扫描所有传入POST
正确的令牌的请求,如果令牌丢失或无效拒绝该请求。
我想使用AJAX一些POST请求,但表示请求没有CSRF令牌availabnle。 这些网页具有无<form>
元素挂接到和我宁愿不浑浊了标记插入令牌作为隐藏值。 我想做到这一点的好办法是揭露像VEW /get-csrf-token/
返回用户的令牌,依靠浏览器的跨站点脚本规则,以防止有人恶意网站的请求它。
这是一个好主意吗? 是否有防止CSRF攻击,同时还允许AJAX请求更好的方法?
如果你知道你将需要CSRF令牌AJAX请求,可以随时将它嵌入在HTML中的某个地方; 那么你可以通过遍历DOM找到它通过JavaScript。 这样,你仍然可以访问令牌,但你不通过API曝光。
为了换一种说法:做通过Django的模板 - 不通过URL调度。 它更安全的这种方式。
更新 :下面的是真实的,如果所有的浏览器和插件得到适当执行应该是真实的。 不幸的是,我们现在知道,他们都没有,和浏览器插件和重定向的某些组合可以允许攻击者提供跨域请求任意头。 不幸的是,这意味着即使使用AJAX请求“X-请求 - 由于:XMLHttpRequest的”头现在必须CSRF保护。 其结果是,Django的不再免除CSRF保护Ajax请求 。
原来的答案
值得一提的是,保护AJAX请求从CSRF是不必要的,因为浏览器不允许跨站点AJAX请求。 事实上,Django的CSRF中间件现在自动免除CSRF令牌扫描AJAX请求 。
如果你实际上是检查从CSRF扫描X-要求,随着头的服务器端的“XMLHttpRequest的”值(Django的那样),而只有真正免除AJAX请求这是唯一有效的。
取消,我错了。 (见注释)。你可以防止你的保证如下JSON规范的漏洞:请务必先返回一个对象字面作为顶级对象。 (我不能保证不会有进一步的攻击。想象一下,一个浏览器提供访问其window.onerror事件失败代码!)
你可以不依赖于跨站点脚本规则,以保持AJAX响应私人。 例如,如果您返回CSRF令牌作为JSON,恶意网站可以重新定义字符串或数组构造函数和请求资源。
bigmattyh是正确的:你需要的地方嵌入令牌的标记。 或者,你可以拒绝这样做有一个引用者不符合任何职位。 这样的话,只能用过分热心的软件防火墙的人会很容易受到CSRF。