I am implementing web app using rails 4.2.0 and ruby 2.2.0 and facing problem that any time request in done new session is set. In that case I cannot save anything to session since it's gone. Also that leads to situation that authenticity token cannot be checked.
For testing purpose forgery protection is disabled in ApplicationController, so that's not reason why session is reset.
class ApplicationController < ActionController::Base
#protect_from_forgery with: :null_session
skip_before_action :verify_authenticity_token `
end
I am using active record store to save session, but same happens for cookie store:
MyApp::Application.config.session_store :active_record_store, :key => '_myapp_session', domain: :all, tld_length: 2
Every time request is done new entry to sessions table is inserted with new sessions_id and session cookie in browser points to new session.
Any ideas what could reset session?
This happens only in production environment. In development everything is fine.
Your issue is due to the call to skip_before_action :verify_authenticity_token; if the authenticity token is not verified, Rails will reset the session. You also want to re-enable protect_from_forgery.
I've also seen AJAX requests without an authenticity token to cause the session to reset, again more detail here: http://www.kalzumeus.com/2011/11/17/i-saw-an-extremely-subtle-bug-today-and-i-just-have-to-tell-someone/
Ref: https://stackoverflow.com/a/11943243/449342
Related
I'm building a Rails app that needs to receive POST'd emails from Mailgun. All OK, I have a controller and routes for that.
All requests receives HTTP 422 because Rails says Invalid Authenticity Token, which is really expected in this case.
I won't use rack-cors because I only allow Mailgun proceeding requests authenticating with its own signature mechanism.
Here my question: Should I use skip_before_action :verify_authenticity_token or should I use protect_from_forgery with: :null_session?
I ended up using protect_from_forgery with: :null_session as it won't contaminate any existing session.
I used SAML strategy for devise (https://github.com/apokalipto/devise_saml_authenticatable).
I did some modifications to it and I see that if a user isn't authenticated it goes and authenticate a user and I log that sucess!() called. As result, browser is getting a session cookie.
The browser coming back to my website with this session cookie. However, warden requires to authenticate again (leading to never ending authentication loop) instead of just letting this user through.
My question is: How can I debug it to see why warden calls authentication (vs just letting it through).
I added before_action to ApplicationController and did puts request.env. I see that session cookie is coming. However, I am not sure what should be the next step to check what's going on.
In Rails, using devise, if a CSRF Check fails then the user's current session is cleared, i.e., logs the user out, because the server assumes it's an attack (which is the correct/desired behavior).
But the request, is completed, hence the user record is still created. Hacker can then log in correctly.
How can I stop the method from continuing once devise realises auth_token is incorrect?
Devise doesn't do any checking of the auth token - it's action controller which does this (although it does call handle_unverified_request on your controller so that you can customise behaviour). In rails 4 and higher you can also specify what happens by default when the auth token is invalid:
protect_from_forgery with: :exception
causes an exception to be raised, which would stop the request being processed.
However I am not sure what this buys you though - CSRF is so that an attacker cannot abuse the fact that the user is already logged into your application, but if the attacker has a valid set of credentials then they don't need to do CSRF in the first place.
A few users are getting a 422 ActionController::InvalidAuthenticityToken error when POSTing a form.
It happens to a minority of users some of the time. If they try their request again later, it often works.
The authenticity token is getting sent along in every case. I'm assuming the client isn't sending the session cookie along with the POST (that would explain why the server can't verify the token). Why would this be?
Finally, the form is submitted via javascript ($('#new_user')[0].submit()), would that somehow prevent the session cookie from being sent?
Disabling the verify_authenticity_token before_filter is unfortunately not an option.
We have run into this scenario with one of our apps. We store our sessions in memcached and if the session is evicted from the cache or the session expires any subsequent post/put/delete raised a 422. We got round this by implementing a before filter 'requires_login?' that checked the session and logout the user out if the session had expired. We then moved the method protect_from_forgery in the application controller to run after requires_login?
E.G
before_filter :requires_login?
protect_from_forgery
Hope this makes sense
I have a simple rails app with a single controller. I have a "before filter" for some of the methods of my controller, where I check if the user is logged in by looking at the session object:
#user = User.where(:id => session[:user_id]) if session[:user_id]
In a "login" method of my controller, I do:
session[:user_id] = user.id
Pretty usual stuff. If I access my app from a web browser (Chrome), everything works fine. However, when I use NSURLRequest from my iOS app to access my rails app, the server always creates a new session for each request. It never seems to be able to identify the existing session, even though the request is sending the cookie with the proper session ID in it. In fact, if I look at the "cookies" object in my rails app, I can see it contains the session ID. However, the session object is always empty! Not sure why the server is not able to retrieve the session. I'm using Passenger Phusion. Any suggestions?
If you are POSTing to your login page, and the post does not include a CSRF token matching the token in the session, then Rails will fail the request and invalidate/reset the session as a security precaution.
To fix it, simply read the CSRF token out of the session and include it in your request, or turn off CSRF token checking, you can place skip_before_filter :verify_authenticity_token in your controller to skip the CSRF protection checks. Note that the latter approach does open potential security holes, so including the tokens and checking them is recommended if it is at all viable.