Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - invalid authenticity token error for cached form

I'm working on a Rails app (version 4.2.5) that uses the rack-offline gem to cache a form that users can fill out when they have no internet connection (entries are stored as localStorage objects which can be submitted later when user has connectivity). However, when the form is submitted, I am getting the error

ActionController::InvalidAuthenticityToken in EntriesController#create

This occurs when I open a new browser window while the Rails server is off and navigate to http://localhost:3000/entries/new (the page has been cached - it renders just fine), fill out the form, then turn the server back on and try to submit.

From my Entries controller:

def create
    @entry = Entry.create(entry_params)
    redirect_to "http://localhost:3000/entries"
end

And the Application controller:

class ApplicationController < ActionController::Base
    protect_from_forgery with: :exception
end

And the in my layout view includes <%= csrf_meta_tags %>

Are there any ways that I can get around this issue without compromising the security of the app?

EDIT In the Application controller, I replaced

protect_from_forgery with: :exception

with

protect_from_forgery with: :null_session

and this solved the problem. However, I don't know enough about what all of this means to understand whether or not this creates a security vulnerability. Does it? (PS - I really want to avoid security vulnerabilities)

like image 910
skwidbreth Avatar asked Oct 16 '25 16:10

skwidbreth


1 Answers

The csrf_meta_tags are useful for ajax form submissions if you have javascript that's smart enough to use them. Otherwise you need to put a regular form field with the token into your form:

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

This will likely fix your issue if you are in the case where you have somehow built a form without including the authenticity token.

Here are some other ideas:

  1. check to make sure the authenticity token is actually being sent to the server by inspecting the HTTP exchange
  2. ensure the server that served your form is the same as the one that's receiving the form submission (or at least that the secret_key_base matches between the servers)
  3. ensure the session cookie you used to retrieve the form isn't missing or expired when you submit the form
  4. speaking of cookies, make sure the session cookie you send is exactly the same one as the one you retrieved when you requested the form. I've seen this happen when you have multiple cookies with the same name with multiple different domain fields set. You can start by clearing them all to see what you end up with by the end.
like image 61
Stephen Crosby Avatar answered Oct 18 '25 07:10

Stephen Crosby



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!