【问题标题】:security safe to disable csrf tokens for json rails calls?安全地禁用 json rails 调用的 csrf 令牌?
【发布时间】:2012-05-27 09:48:20
【问题描述】:

我有一个现有的 Rails 后端网站,它对服务器进行 json 调用。现在,我正在开发一个移动 iOS 应用程序以使用相同的后端并以 json 格式发送呼叫。但是,移动请求失败:

WARNING: Can't verify CSRF token authenticity

在 stackoverflow 周围搜索,许多人建议使用以下方法禁用 csrf 检查 json 调用:

# Or this in your application_controller.rb
def verified_request?
  if request.content_type == "application/json"
    true
  else
    super()
  end
end

但我的问题是,我不明白这如何防止 json 格式的 csrf 攻击?攻击者总是可以从他们的站点向我们的端点发送一个 json 请求。有人对此有见解吗?我找不到任何明确的答案。

【问题讨论】:

    标签: ios security ruby-on-rails-3.1


    【解决方案1】:

    您所描述的内容很容易使用 Flash 加以利用:

            var request:URLRequest = new URLRequest("http://stackoverflow.com"); 
            request.requestHeaders.push(new URLRequestHeader('Content-Type', 'application/json'));      
            request.data = unescape('{"a":1,"b":{"c":3}}');
            request.method = URLRequestMethod.POST;
            navigateToURL(request, '_blank');   
    

    如果您查看CSRF prevention cheat sheet,您可以检查引荐来源网址以确保其来自您信任的域。如果引用者为空,则它可能源自 https url,因此应视为失败。依赖 Ruby 的 CSRF 令牌是一种更强的 CSRF 保护形式。

    【讨论】:

    • 谢谢鲁克。是的,它可以破解 csrf 中的 json 调用。查看该页面可以让我更深入地了解我们可以解决谁。但是您知道如何使用 Rails 生成的 CSRF 令牌,以便移动应用可以使用它们并发送请求吗?
    • @Anish 你可以引导它,也许有一个总是返回令牌的静态 get 调用。
    • "您可以检查引用者以确保其来自您信任的域。"当然,这些很容易被伪造
    • @SooDesuNe 虽然欺骗你自己的referer很简单,但在CSRF攻击中是不可能做到的。请阅读上面链接的 CSRF 预防备忘单。
    • 如果您有一个返回令牌的 API,那么是什么阻止攻击者调用该 API 来获取令牌,然后将其传递给其他 API?
    【解决方案2】:

    这是对 ajax 的修复

    从 rails 获取 csrf_token,或者如果使用其他东西,从 meta 获取

    // js file
    var csrf_token = $('meta[name=csrf-token]').attr('content');
    

    或

    //js.erb file
    var csrf_token = "<%= request.session["<%= _csrf_token %>"] %>";
    

    然后将这个添加到js中

    $("body").bind("ajaxSend", function(elm, xhr, s){
       if (s.type == "POST") {
        // place lines mentioned above here
        // line goes here...
        xhr.setRequestHeader('X-CSRF-Token', csrf_token);
       }
    });
    

    【讨论】:

    • JS 示例可能是一个糟糕的示例,因为您将预编译您的资产并且不会动态重新生成。只是一个提示。那可能真的很可怕,因为它可以在开发中工作,但不能在生产中工作。
    • @StingeyB 感谢您的评论 :-) 我在最后一段代码中添加了一条评论,指示用户将上述行放在何处。这应该可以在资产预编译后继续存在,同意吗?
    【解决方案3】:

    您可以采取的一种方法是保留 CSRF 检查,但根据存在的 http 标头禁用。如果您的 json 请求有 JWT 令牌,您可以在相关控制器中执行类似的操作。

    protect_from_forgery with: :exception, unless: -> { some_auth_token.valid? }
    

    表单提交将无法设置 http 标头,因此 csrf 将对其进行保护。

    您的 json 请求应该有一个 Authorization 标头以确保安全。

    【讨论】:

      猜你喜欢
      • 2015-08-17
      • 2016-06-09
      • 1970-01-01
      • 2018-09-22
      • 2016-02-27
      • 2021-10-17
      • 2016-09-28
      • 2010-10-05
      • 1970-01-01
      相关资源
      最近更新 更多