代码之家  ›  专栏  ›  技术社区  ›  John Millikin

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

  •  15
  • John Millikin  · 技术社区  · 16 年前

    姜戈和 CSRF protection middleware ,它生成一个唯一的每个会话令牌以在表单中使用。它扫描所有传入的 POST 请求正确的令牌,如果令牌丢失或无效,则拒绝请求。

    我想在一些POST请求中使用Ajax,但是说请求没有可用的CSRF令牌。页面没有 <form> 要挂接的元素,我不希望混淆标记,将标记作为隐藏值插入。我想做这件事的一个好方法是暴露一种蔬菜 /get-csrf-token/ 要返回用户的令牌,请依赖浏览器的跨站点脚本规则,以防止恶意站点请求它。

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

    3 回复  |  直到 8 年前
        1
  •  12
  •   Sam Hasler    16 年前

    如果您知道您将需要用于Ajax请求的CSRF令牌,那么您可以将它嵌入HTML中的某个地方;然后您可以通过JavaScript通过遍历DOM找到它。这样,您仍然可以访问令牌,但不会通过API公开它。

    换一种方式:通过Django的模板来实现,而不是通过URL调度器。这样更安全。

        2
  •  16
  •   Carl Meyer    13 年前

    更新 :以下是正确的,如果所有浏览器和插件都正确实现,则应该是正确的。不幸的是,我们现在知道它们不是,浏览器插件和重定向的某些组合允许攻击者在跨域请求上提供任意的头文件。不幸的是,这意味着即使具有“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-requested-with头服务器端的“xmlhttprequest”值(Django是这样做的)时有效,并且仅从CSRF扫描中免除真正的Ajax请求。

        3
  •  1
  •   Tim has moved to Codidact    16 年前

    取消那个,我错了。(见评论) 您可以通过确保JSON遵循规范来防止这种攻击:始终确保返回一个对象文本作为顶级对象。(我不能保证不会有进一步的剥削。想象一下一个浏览器提供对window.onerror事件中失败代码的访问!)

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

    Bigmattyh是正确的:您需要将令牌嵌入标记中的某个位置。或者,您可以拒绝任何 有一个裁判 比赛。这样,只有那些有着过分狂热的软件防火墙的人才会容易受到CSRF的攻击。