Django附带了CSRF protection middleware,它生成一个惟一的每个会话的令牌,用于表单中。它扫描所有传入的POST请求以查找正确的令牌,如果该令牌缺失或无效,则拒绝该请求。
我想对一些POST请求使用AJAX,但是这些请求没有可用的CSRF令牌。页面没有可以挂接的<form>元素,我不想弄乱标记,将标记作为隐藏值插入。我认为这样做的一个好方法是公开像/get-csrf-token/这样的脚本来返回用户的令牌,依靠浏览器的跨站点脚本规则来防止恶意站点请求令牌。
这是个好主意吗?有没有更好的方法来防御CSRF攻击,同时仍然允许AJAX请求?
发布于 2008-09-28 01:36:36
如果您知道AJAX请求将需要CSRF令牌,则可以始终将其嵌入到HTML中的某个位置;然后,您可以通过遍历DOM通过Javascript找到它。这样,您仍然可以访问令牌,但不会通过API公开它。
换句话说:通过Django的模板完成,而不是通过URL dispatcher。这样更安全。
发布于 2009-02-10 17:55:12
更新:下面是真的,如果所有的浏览器和插件都被正确实现,也应该是真的。不幸的是,我们现在知道它们不是,并且浏览器插件和重定向的某些组合可以允许攻击者在跨域请求上提供任意标头。不幸的是,这意味着即使是带有"X-Requested- with : XMLHttpRequest“头的AJAX请求现在也必须受CSRF保护。因此,Django no longer exempts Ajax requests from CSRF protection。
原始答案
值得一提的是,保护来自CSRF的AJAX请求是不必要的,因为浏览器不允许跨站点AJAX请求。事实上,Django CSRF中间件现在是automatically exempts AJAX requests from CSRF token scanning。
这只在你实际检查X- requests -With header服务器端的"XMLHttpRequest“值时才有效( Django就是这样做的),并且只从CSRF扫描中排除真正的AJAX请求。
发布于 2008-09-28 17:58:09
取消了,我错了。(参见注释)您可以通过确保您的JSON遵循以下规范来防止利用漏洞:始终确保您返回一个对象文字作为顶级对象。(我不能保证不会有更多的漏洞。想象一下,浏览器在其window.onerror事件中提供对失败代码的访问!)
您不能依靠跨站点脚本规则来保证AJAX响应的私密性。例如,如果将CSRF令牌作为JSON返回,恶意站点可能会redefine the String or Array constructor并请求资源。
bigmattyh是正确的:您需要将标记嵌入到标记中的某个位置。或者,你可以拒绝任何do有一个不匹配的引用的帖子。这样,只有过度热衷于软件防火墙的人才容易受到CSRF的攻击。
https://stackoverflow.com/questions/144696
复制相似问题