2

我通过添加以下内容在 Controller 中应用CSRF :

  class ApplicationController < ActionController::Base
     protect_from_forgery
  end

我使用Postman向我的 API 发出发布请求。有趣的结果是我无法验证CSRF,但我发送的数据仍然被插入到数据库中。

这是服务器日志。

 Processing by Api::ListingsController
   Parameters: {"listing"=>{...}}
 Can't verify CSRF token authenticity
   (0.2ms)  BEGIN
 SQL (0.6ms)  INSERT INTO "listings" ...
   (0.4ms)  COMMIT
 Completed 201 Created in 54ms (Views: 0.2ms | ActiveRecord: 6.3ms)

似乎一切都很好,数据现在在数据库中!为什么CSRF不起作用?

任何人都可以给出任何解释吗?

4

2 回答 2

3

csrf 令牌不匹配可能触发 3 种行为:

  • 引发异常 ( :exception)
  • 将会话重置为新的空会话 ( :reset_session)
  • 为请求使用空会话,但不要完全重置它 ( :null_session)

最后两个的基本原理是 CSRF 攻击的目的通常是滥用用户已经登录的事实,因此浏览器将发送会话 cookie 和请求。因此,重置或忽略会话(假设这是存储凭据的位置)将使请求作为未经身份验证的请求继续进行。

如果应用程序不需要用户登录,那么:null_session:reset_session允许请求继续进行。

多年来,默认行为发生了变化,但从 rails 4.2 开始是 is :null_session。您可以通过指定一个with选项来更改它protect_from_forgery

于 2015-10-30T09:50:01.443 回答
0

ApplicationController你可以添加

class ApplicationController < ActionController::Base
    protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format      == 'application/json' }
    # Or
    # skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }
end
于 2015-10-30T09:28:01.817 回答