【问题标题】:How to protect against CSRF when using Backbone.js to post data?使用 Backbone.js 发布数据时如何防止 CSRF?
【发布时间】:2013-08-10 02:20:45
【问题描述】:

Backbone.js 在后台处理向服务器发布数据,因此没有简单的方法可以在负载中插入 CSRF 令牌。在这种情况下,如何保护我的网站免受 CSRF 的影响?

在这个 SO 答案中:https://stackoverflow.com/a/10386412/954376,建议验证 x-Requested-By 标头是否为 XMLHTTPRequest。这足以阻止所有 CSRF 尝试吗?

在 Django 文档中,建议在每个 AJAX 请求的另一个自定义标头中添加 CSRF 令牌:https://docs.djangoproject.com/en/1.5/ref/contrib/csrf/#ajax。有必要吗?

我了解如果攻击使用隐藏形式,我只要确保请求来自 XMLHTTPRequest 就很安全。但是有没有什么可以伪造header的CSRF攻击技巧呢?

【问题讨论】:

  • “我只是确保请求来自 XMLHTTPRequest 是安全的”——你无法确保。

标签: javascript backbone.js web csrf


【解决方案1】:

您可以使用prefilter 将令牌添加到所有请求:

$.ajaxPrefilter(function(opts) {
    if (opts.data) {
        opts.data += "&";
    }
    opts.data += "csrfToken=" + token;
});

如果您不总是发送令牌,则可能需要添加额外的逻辑。

【讨论】:

  • 感谢您的回答!所以只是验证 X-Requested-with 标头不好?什么样的攻击可以伪造这个header?
  • @NeoWang 那些在 Flash 等插件中使用错误的人。在正常的 CSRF 情况下,您无法伪造标头,因此没有错误就可以了。您可能会认为总是只发送和检查令牌比有时检查令牌和有时检查标头要简单得多。
【解决方案2】:

为所有 jQuery.ajax 调用设置全局 CSRF-token:

$(function(){ 
  $.ajaxSetup({
    headers: {'X-CSRFToken': CSRF_TOKEN}
  });
})

通过覆盖 Backbone.sync 为 Backbone 设置令牌:

var oldSync = Backbone.sync;
Backbone.sync = function(method, model, options){
  options.beforeSend = function(xhr){
    xhr.setRequestHeader('X-CSRFToken', CSRF_TOKEN);
  };
  return oldSync(method, model, options);
};

编辑:修正了在 cmets 中 Kadam 点的错字

【讨论】:

  • 标题键的正确拼写是X-CSRFToken。您的第一个建议中有一个额外的破折号打破了它。
  • @kadam 标题键的正确拼写取决于服务器。例如,Express 3 使用X-CSRF-Tokenexpressjs.com/3x/api.html#csrf
【解决方案3】:

我知道这是一个有点老的问题,但我会为此留下一个指向 AMD 模块的 github repo 的链接:

https://github.com/kuc2477/backbone.csrf.git免责声明:我是模块的作者

【讨论】:

    【解决方案4】:

    这是一个更新版本,基于 Django 1.7(使用 jQuery cookie 插件)

    oldSync = Backbone.sync
    Backbone.sync = (method, model, options) ->
    
        csrfSafeMethod = (method) ->
            # these HTTP methods do not require CSRF protection
            /^(GET|HEAD|OPTIONS|TRACE)$/.test method
    
        options.beforeSend = (xhr, settings) ->
            if !csrfSafeMethod(settings.type) and !@crossDomain
                xhr.setRequestHeader 'X-CSRFToken', $.cookie('csrftoken')
            return
        oldSync method, model, options
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 2013-10-26
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      • 2011-06-24
      相关资源
      最近更新 更多