ActionController::InvalidAuthenticityToken
I had the same issue but with pages which were page cached. Pages got buffered with a stale authenticity token and all actions using the methods post/put/delete where recognized as forgery attempts. Error (422 Unprocessable Entity) was returned to the user.
The solution for Rails 3:
Add:
skip_before_filter :verify_authenticity_token
or as "sagivo" pointed out in Rails 4 add:
skip_before_action :verify_authenticity_token
On pages which do caching.
As @toobulkeh commented this is not a vulnerability on :index
, :show
actions, but beware using this on :put
, :post
actions.
For example:
caches_page :index, :show
skip_before_filter :verify_authenticity_token, :only => [:index, :show]
Reference: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html
Note added by barlop- Rails 4.2 deprecated skip_before_filter in favour of skip_before_action https://guides.rubyonrails.org/4_2_release_notes.html "The *_filter family of methods have been removed from the documentation. Their usage is discouraged in favor of the *_action family of methods"
For Rails 6 (as "collimarco" pointed out) you can use skip_forgery_protection
and that it is safe to use it for a REST API that doesn't use session data.
For me the cause of this issue under Rails 4 was a missing,
<%= csrf_meta_tags %>
Line in my main application layout. I had accidently deleted it when I rewrote my layout.
If this isn't in the main layout you will need it in any page that you want a CSRF token on.
There are several causes for this error, (relating to Rails 4).
1. Check <%= csrf_meta_tags %>
present in page layout
2. check authenticity token is being sent with AJAX calls if using form_for
helper with remote: true
option.If not you can include the line <%= hidden_field_tag :authenticity_token, form_authenticity_token %>
withing the form block.
3. If request is being sent from cached page, use fragment caching to exclude part of page that sends request e.g. button_to
etc. otherwise token will be stale/invalid.
I would be reluctant to nullify csrf protection...