首页 文章

暴露会话的CSRF保护令牌是否安全?

提问于
浏览
15

Django附带CSRF protection middleware,它生成一个唯一的每会话令牌,用于表单 . 它会扫描所有传入的 POST 请求以获取正确的令牌,并在令牌丢失或无效时拒绝该请求 .

我有CSRF令牌可供选择 . 这些页面没有 <form> 元素可以挂钩,我宁愿不把标记作为隐藏值插入标记 . 我认为这样做的一个好方法是公开像 /get-csrf-token/ 这样的vew来返回用户's token, relying on browser'的跨站点脚本规则,以防止恶意站点请求它 .

这是一个好主意吗?是否有更好的方法来防止CSRF攻击,同时仍允许AJAX请求?

3 回答

  • 1

    如果你知道你需要为AJAX请求提供CSRF令牌,你可以随时将它嵌入到某个地方的HTML中;然后你可以通过遍历DOM找到它 . 这样,您仍然可以访问令牌,但您不会通过API公开它 .

    换句话说:通过Django的模板 - 而不是通过URL调度程序 . 这种方式更加安全 .

  • 12

    UPDATE :以下情况属实,如果所有浏览器和插件都已正确实施,则应该如此 . 不幸的是,我们现在知道它们不是,并且浏览器插件和重定向的某些组合可以允许攻击者在跨域请求上提供任意标头 . 不幸的是,这意味着即使带有"X-Requested-With: XMLHttpRequest"标头的AJAX请求现在也必须受CSRF保护 . 结果,Django no longer exempts Ajax requests from CSRF protection .

    Original Answer

    值得一提的是,保护来自CSRF的AJAX请求是不必要的,因为浏览器不允许跨站点AJAX请求 . 事实上,Django CSRF中间件现在automatically exempts AJAX requests from CSRF token scanning .

    这仅在您实际检查X-Requested-With标头服务器端的“XMLHttpRequest”值(Django所做的)时才有效,并且只从CSRF扫描中免除真正的AJAX请求 .

  • 16

    Cancel that, I was wrong. (See comments.) 您可以通过确保JSON遵循规范来阻止漏洞利用:始终确保将对象文字作为顶级对象返回 . (我可以进一步利用 . 想象一下,浏览器在其window.onerror事件中提供对失败代码的访问!)

    您不能依赖跨站点脚本规则来保持AJAX响应的私密性 . 例如,如果将CSRF令牌作为JSON返回,则恶意站点可以redefine the String or Array constructor并请求该资源 .

    bigmattyh是正确的:您需要将标记嵌入标记中的某个位置 . 或者,您可以拒绝 do 具有 doesn't 匹配的引用的任何POST . 这样,只有拥有过度热心的软件防火墙的人才会容易受到CSRF的攻击 .

相关问题