Rails 4跳过protect_from_forgery进行API操作

31 api json ruby-on-rails csrf ruby-on-rails-4

我一直在使用API​​实现Rails 4应用程序.我希望能够通过手机和webapp本身调用API.我在研究时遇到了这个问题protect_from_forgery:

重要的是要记住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
Run Code Online (Sandbox Code Playgroud)

我想这样做,但我有一些保留/问题:

  1. 这个解决方案似乎让CSRF漏洞了,因为现在攻击者可以使用onclick发布JSON 的javascript 创建链接?
  2. 检查API令牌是否合理?即,如果不是跳过真实性检查,允许它检查失败并在handle_unverified_requestapi令牌存在且当前用户正确的情况下恢复,该怎么办?
  3. 或者我可能只是让webapp和移动设备在HTTP头中发送CSRF令牌?这样安全吗?如果手机没有开始呈现HTML表单,那么手机如何获得CSRF令牌呢?

编辑以澄清:

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

Ore*_*zor 8

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

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

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

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

sin*_*law 6

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

AngularJS遵循这种方法,如此处所述.

至于你的前两个问题:

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

实际上,这就是为什么你不应该在API中禁用CSRF令牌的原因.

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

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

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

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