Rails 4 : Can't verify CSRF token authenticity but data still insert into database

774 Views Asked by At

I apply the CSRF in Controller by adding this:

  class ApplicationController < ActionController::Base
     protect_from_forgery
  end

and I do a post request to my API using Postman. The funny result is I can't verify CSRF, but the data I send still be inserted into DB.

Here is the server log.

 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)

Seems everything is fine, and data is in DB now! Why is CSRF not working?

Anyone can give any explains?

2

There are 2 best solutions below

2
On

There are 3 behaviours that a csrf token mismatch can trigger:

  • raise an exception (:exception)
  • reset the session to a new, empty session (:reset_session)
  • use an empty session for the request, but don't reset it completely (:null_session)

The rationale for the last 2 is that the point of a CSRF attack is usually to abuse the fact that the user is already logged in and thus the browser will send session cookies with the request. Therefore reseting or ignoring the session (assuming that is where credentials are stored) will make the request proceed as an unauthenticated request.

If the application doesn't require the user to be logged in then :null_session and :reset_session will allow the request to proceed.

The default behaviour has changed over the years, but as of rails 4.2 is is :null_session. You can change it by specifying a with option to protect_from_forgery

1
On

In ApplicationController you can add

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