如何确保 Rails API 不受 CSRF 的影响? [英] How to make sure Rails API is secured from CSRF?

查看:27
本文介绍了如何确保 Rails API 不受 CSRF 的影响?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在开发带有 REST API 的 Rails 应用程序,以便从移动应用程序访问.

I've been developing Rails app with REST API for access from mobile application.

效果很好.当用户从移动应用程序登录时,他会获得 auth_token,他将在未来对 API 的请求中使用该令牌.问题是 API 也可以通过路径/api/v1/... 从网络访问,因此,必须保护它免受 CSRF 的影响.

It works quite well. When user logs in from mobile application, he gets auth_token that he uses in his future requests to API. The issue is that API is also accessible from web by going to path /api/v1/... and because of this, it has to be protected from CSRF.

我有从 ApplicationController 继承的 BaseApiController 类,它具有 protect_from_forgery 启用".示例如下:

I have BaseApiController class which inherits from ApplicationController that has protect_from_forgery "enabled". Here's example:

class Api::V1::BaseApiController < ApplicationController
  # ...
end

class ApplicationController < ActionController::Base
  protect_from_forgery
  # ...
end

现在,当我使用 auth_token 对 API 执行非 GET 请求时,我的请求已成功完成,但在日志中我可以看到著名的 警告:无法验证CSRF 令牌真实性.如果我从 BaseApiController 中删除 protect_from_forgery,我不会收到任何警告(显然),但是我的 API 容易受到 CSRF 攻击(我制作了一个简单的 HTML 表单,在没有 protect_from_forgery 的情况下成功地跨域更改数据.

Now, when I do non-GET requests to my API, with auth_token, my request gets completed successfully, but in the logs I can see the famous WARNING: Can't verify CSRF token authenticity. If I remove protect_from_forgery from my BaseApiController, I don't get any warnings (obviously), but then my API is vulnerable to CSRF attacks (I made a simple HTML form that successfully changes the data across domains when there's no protect_from_forgery).

我的问题是:如何确保我的 API 保持安全,同时在执行非 GET 请求时删除警告?

My question is: How to assure my API stays secure, but also remove the warning when doing non-GET requests?

这是我提出的解决方案之一,但它看起来更像是一种黑客行为并执行一个额外的数据库查询:

Here's one of the solutions I've come up with, but it looks more like a hack and executes one extra DB query:

class Api::V1::BaseApiController < ApplicationController
  # ...
  def verified_request?
    super || User.where(authentication_token: params['auth_token']).count > 0
  end
end

有关该项目的更多详细信息:Rails 3.2.14、Devise、AngularJS.可以在此处找到该项目的源代码.

More details about the project: Rails 3.2.14, Devise, AngularJS. The project's source code can be found here.

推荐答案

您可能会看到有人建议 CSRF 不是 API 请求的问题(开始时没有状态,所以无论如何要劫持什么?),所以有些人建议使用以下方法来简单地消除警告:

You may see people suggest that CSRF is not an issue for API requests (there is no state to begin with, so what is there to hijack anyhow?), so some suggest the following to simply eliminate the warning:

skip_before_filter :verify_authenticity_token, :only => [:your_method]

然而,有一些评论说可以使用各种基于 Flash 和 Java 的方法通过 text/plain 提交 CSRF.我相信这就是不久前在 rails 中安装安全补丁的原因:http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails/

However, there was some commentary that it is possible to commit CSRF with text/plain using various Flash and Java-based methods. I believe that was the reason for the security patch in rails a while back: http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails/

无论如何,可以在此处找到实际检查真实性令牌的好解决方案:警告:无法验证 CSRF 令牌真实性 rails

In any event, a good solution that actually checks for an authenticity token can be found here: WARNING: Can't verify CSRF token authenticity rails

它涉及在您的请求中实际设置标头.

It involves actually setting the header in your request.

祝你好运!

这篇关于如何确保 Rails API 不受 CSRF 的影响?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆