Rails 4跳过protect_from_forgery进行API操作

时间:2014-05-21 04:00:31

标签: ruby-on-rails json api ruby-on-rails-4 csrf

我一直在使用API​​实现Rails 4应用程序。我希望能够通过手机和webapp本身调用API。我在研究protect_from_forgery时遇到了this note

  

重要的是要记住XML或JSON请求也会受到影响,如果您正在构建API,则需要以下内容:

class ApplicationController < ActionController::Base
  protect_from_forgery
  skip_before_action :verify_authenticity_token, if: :json_request?

  protected

  def json_request?
    request.format.json?
  end
end

我正在考虑这样做,但我有一些保留/问题:

  1. 这个解决方案似乎让CSRF漏洞了,因为现在攻击者可以使用发布JSON的onclick javascript创建一个链接?
  2. 检查API令牌是否合理?即如果代替跳过真实性检查,如果api令牌存在并且当前用户正确,则允许它在handle_unverified_request中检查失败并恢复?
  3. 或者我应该制作网络应用和移动设备send the CSRF token in the HTTP headers?这样安全吗?鉴于它不是以HTML格式开头,手机甚至会如何获得CSRF令牌?
  4. 编辑以澄清:

    我更关心webapp用户点击精心设计的CSRF链接。移动用户经过身份验证,授权,拥有API密钥,因此我并不关心它们。但是,通过为webapp用户启用CSRF保护,移动用户将无法使用受保护的API。我想知道处理这个的正确策略,我不相信Rails文档给出了正确的答案。

2 个答案:

答案 0 :(得分:9)

攻击者可以随心所欲地在你的控制器上使用CURL,但如果你的API需要身份验证,他们就无法到达任何地方。

让API消费者发送CSRF并不是CSRF所做的。要做到这一点,您需要实现一种敲门机制,其中您的客户端首先访问授权端点以获取代码(也称为CSRF),然后在POST中提交它。这对于移动客户来说很糟糕,因为它使用的是带宽,功率和滞后性。

无论如何,如果它的授权客户终究击中你的控制器,它实际上是伪造的(即CSR中的F)吗?

答案 1 :(得分:5)

在HTTP标头中发送CSRF令牌确实是一种常见的方法。它确保客户端以某种方式获得有效令牌。例如,精心设计的CSRF链接将与凭证cookie一起发送,但标题将不包含CSRF令牌。您自己在客户端上的javascript将可以访问域cookie,并且可以将令牌从cookie复制到所有XHR请求的标头。

AngularJS遵循这种方法,as explained here

关于你的前两个问题:

  
      
  1. 这个解决方案似乎让CSRF漏洞......
  2.   

确实,这就是为什么你不应该在你的API中禁用CSRF令牌。

  
      
  1. 检查API令牌是否合理? ...
  2.   

可能不是。考虑以下内容(来自OWASP):

  

GET请求中的CSRF令牌可能在以下几个位置泄露:浏览器历史记录,HTTP日志文件,指向记录HTTP请求第一行的网络设备,以及受保护站点链接到外部站点时的Referer标头

一般建议:不要试图发明轮子。 OWASP有一个名为REST Security Cheat Sheet的页面以及之前链接的页面。您可以遵循Angular方法(将令牌从cookie复制到每个XHR请求上的标头)和常规非ajax表单,确保只使用POST和隐藏字段,这通常在静态服务器表单的CSRF保护中完成