omniauth-rails_csrf_protection: token_verifier.rb:34 ActionController::InvalidAuthenticityToken
Please complete all sections.
Configuration
- Provider Gem:
omniauth-rails_csrf_protection 0.1.2
- Ruby Version:
2.6.5
- Framework:
Rails
- Platform:
Heroku
Expected Behavior
Recent changes to csrf protection seem to cause a non-rescuable exception. Using
- devise 4.7.1
- omniauth 1.9.0
- omniauth-google-oauth2 0.7.0
- omniauth-oauth2 1.6.0
- omniauth-rails_csrf_protection 0.1.2
application_controller.rb:
rescue_from ActionController::InvalidAuthenticityToken, with: :redirect_and_prompt_for_sign_in
protected
def redirect_and_prompt_for_sign_in
redirect_to(new_user_session_path, alert: 'Please sign in.')
end
I expect that ApplicationController can catch the exception, but it does not.
Actual Behavior
An exception is raised with the following stacktrace.
/GEM_ROOT/gems/omniauth-rails_csrf_protection-0.1.2/lib/omniauth/rails_csrf_protection/token_verifier.rb:34
URL: https://myapp/users/auth/google_oauth2
/GEM_ROOT/gems/omniauth-rails_csrf_protection-0.1.2/lib/omniauth/rails_csrf_protection/token_verifier.rb:34 in call
/GEM_ROOT/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:209 in request_call
/GEM_ROOT/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:188 in call!
/GEM_ROOT/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169 in call
/GEM_ROOT/gems/warden-1.2.8/lib/warden/manager.rb:36 in block in call
/GEM_ROOT/gems/warden-1.2.8/lib/warden/manager.rb:34 in catch
/GEM_ROOT/gems/warden-1.2.8/lib/warden/manager.rb:34 in call
/GEM_ROOT/gems/rack-2.0.7/lib/rack/tempfile_reaper.rb:15 in call
/GEM_ROOT/gems/rack-2.0.7/lib/rack/etag.rb:25 in call
/GEM_ROOT/gems/rack-2.0.7/lib/rack/conditional_get.rb:38 in call
/GEM_ROOT/gems/rack-2.0.7/lib/rack/head.rb:12 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/http/content_security_policy.rb:18 in call
/GEM_ROOT/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:232 in context
/GEM_ROOT/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:226 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/cookies.rb:670 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/callbacks.rb:28 in block in call
/GEM_ROOT/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:98 in run_callbacks
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/callbacks.rb:26 in call
/GEM_ROOT/gems/airbrake-9.5.0/lib/airbrake/rack/middleware.rb:32 in call!
/GEM_ROOT/gems/airbrake-9.5.0/lib/airbrake/rack/middleware.rb:21 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/debug_exceptions.rb:61 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/show_exceptions.rb:33 in call
/GEM_ROOT/gems/railties-5.2.3/lib/rails/rack/logger.rb:38 in call_app
/GEM_ROOT/gems/railties-5.2.3/lib/rails/rack/logger.rb:26 in block in call
/GEM_ROOT/gems/activesupport-5.2.3/lib/active_support/tagged_logging.rb:71 in block in tagged
/GEM_ROOT/gems/activesupport-5.2.3/lib/active_support/tagged_logging.rb:28 in tagged
/GEM_ROOT/gems/activesupport-5.2.3/lib/active_support/tagged_logging.rb:71 in tagged
/GEM_ROOT/gems/railties-5.2.3/lib/rails/rack/logger.rb:26 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/remote_ip.rb:81 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/request_id.rb:27 in call
/GEM_ROOT/gems/rack-2.0.7/lib/rack/method_override.rb:22 in call
/GEM_ROOT/gems/rack-2.0.7/lib/rack/runtime.rb:22 in call
/GEM_ROOT/gems/activesupport-5.2.3/lib/active_support/cache/strategy/local_cache_middleware.rb:29 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/executor.rb:14 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/static.rb:127 in call
/GEM_ROOT/gems/rack-2.0.7/lib/rack/sendfile.rb:111 in call
/GEM_ROOT/gems/actionpack-5.2.3/lib/action_dispatch/middleware/ssl.rb:74 in call
/GEM_ROOT/gems/railties-5.2.3/lib/rails/engine.rb:524 in call
/GEM_ROOT/gems/puma-3.12.1/lib/puma/configuration.rb:227 in call
/GEM_ROOT/gems/puma-3.12.1/lib/puma/server.rb:660 in handle_request
/GEM_ROOT/gems/puma-3.12.1/lib/puma/server.rb:474 in process_client
/GEM_ROOT/gems/puma-3.12.1/lib/puma/server.rb:334 in block in run
/GEM_ROOT/gems/puma-3.12.1/lib/puma/thread_pool.rb:135 in block in spawn_thread
Steps to Reproduce
I apologize (!) but whatever I do in development or production, I can’t seem to recreate this issue, but my end users in production can. I need to isolate exactly what they are doing and will post back.
About this issue
- Original URL
- State: open
- Created 5 years ago
- Comments: 23
Commits related to this issue
- Mitigate CVE 2015-9284 This approach has issues with cookies. Ref: cookpad/omniauth-rails_csrf_protection#8 — committed to diowa/icare by tagliala 4 years ago
- Fixes obscure Auth0 error that only happens in production mode Thanks a lot to @pasih for providing the solution here: https://github.com/cookpad/omniauth-rails_csrf_protection/issues/8\#issuecomment... — committed to adamkasztenny/hybridly by adamkasztenny 3 years ago
- Fixes obscure Auth0 error that only happens in production mode Thanks a lot to @pasih for providing the solution here: https://github.com/cookpad/omniauth-rails_csrf_protection/issues/8\#issuecomment... — committed to adamkasztenny/hybridly by adamkasztenny 3 years ago
I just spent quite some time debugging this. In my case, I was following an auth0 tutorial that instructed to generate a link with
<%= button_to "Login", "auth/auth0", method: :post %>
. I was banging my head to a wall for a long time because of the InvalidAuthenticityToken exception.Turns out that the path had to be “/auth/auth0” (slash in the beginning) for rails to correctly compare the path. Shrug. Maybe this helps someone else. Not sure if this is actually a Rails bug… it seems at least little unfriendly.
+1 Having the same issue
@ybakos sorry for the late reply, and thank you for your report.
This gem actually hooks into Rails request stack by adding itself in
before_request_phase
of OmniAuth’s middleware. If you runrake:middleware
, you can see that the request will hit OmniAuth middleware, raise exception, then skipping your application code (where ApplicationController live) entirely.One way to workaround this issue is to by creating a middleware that rescue
ActionController::InvalidAuthenticityToken
and redirect user to sign in. Something like:Then insert it before
OmniAuth::Builder
:I have not tested the code above, but I hope I can give you some idea.
Thanks @sikachu, just to add to your code from here https://github.com/cookpad/omniauth-rails_csrf_protection/issues/8#issuecomment-550833651
I’ve tested this code in the wild (Rails 7) and it works:
config.middleware.use RescueFromInvalidAuthenticityToken
I had to set
Rails.application.config.action_controller.per_form_csrf_tokens = false
to get around this issue in apps I’ve upgrade to Rails 6.I used the classic
rake app:update
command to upgrade to Rails 6 and that’s the command which changed the cache store (which I saw and approved because I didn’t think it would break anything). This is not necessarily a bug though because by default Rails 6 uses cookie store for sessions AFAIR so it does NOT depend on the cache store, but in my case I changed the session store toCacheStore
(because I use this in production) and that’s why removing the cache store broke the sessions for me.So yeah maybe a little note about that in the Readme could help because the error message is clearly not obvious in this case but it’ll boil down to: “make sure you have a session store that stores stuff” ^^. But people won’t check the gem readme when they get this error I think, they’ll just look it up online and find this issue that’s why I added this comment here 😉 Ideally if we can have a different error message for when the session store is simply returning nil maybe it could make it easier to lead people to the solution.
@jarthod that is very interesting. I feel like that’s a bug in Rails if upgrading to Rails 6 switch your cache store to
:null_store
and break session. Would you mind letting me know which guide you followed and which script actually causing that, as we might want to mention that in the README?Yep, that won’t work as omniauth is hooking into rails at middleware level so we have to be at this level as well.
I will have some time to working on the failure handling this week, and I’ll cut a new version afterward. I’m going to keep this open for now as I want to hear more about the problem with the
cache_store
though.For the record, I recently tried to upgrade my application from
rails 5.2.4.2
torails 6.0.2.2
and I got this error at every form I try to submit, even without oauth if I just submit the login/password devise form ☹️I’m using:
🕵️♂️ But I tried without this gem and saw that I was still getting CSRF errors (less visible though as maybe rescued differently). I followed rails 6 upgrade process which changes
config.cache_store = :memory_store
toconfig.cache_store = :null_store
by default in dev env and that’s what was causing the issue for me, simply because the CSRF token is stored in the session store (which is using cache_store by default) and the default store in dev is now disabled unless you explicitly enable caching.So that’s one thing to look for if you end up having this error, I’m not sure why they made this change at it can break every form by default 🤷♂️, hopefully it’ll help some people 👍
Got it, thanks!
And yes, I think document that the CSRF token will be stored in session would be useful … so I’ll add that.