Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't verify CSRF token authenticity #398

Closed
sburke56 opened this issue Oct 5, 2015 · 10 comments
Closed

Can't verify CSRF token authenticity #398

sburke56 opened this issue Oct 5, 2015 · 10 comments

Comments

@sburke56
Copy link

sburke56 commented Oct 5, 2015

I was trying to update devise_token_auth and ran into an issue where I couldn't logout & login again. I would get an error "Can't verify CSRF token authenticity". I'm using ng token auth with devise token auth. Long story short I narrowed it down to devise token auth v0.1.32 for me is where it breaks. v0.1.32beta9 works.

Here's the project & with a little work it should repeat but I can't promise anything. There is a README.md in the root. Basically it's your standard rails server setup; update the config/database.yml & run.

https://www.dropbox.com/s/77sn1nlfuadbjzx/gdo2.tar.gz?dl=0

Steps to Repeat
db:drop && db:create && db:setup
rails s
browse localhost:3000/#/login
Login: [email protected]
Password: password

Logout and then login again and you will get an error when using devise_token_auth >= v0.1.32.

sburke@sburke-laptop:~/sandbox/gdo2$ bundle
Using actionmailer 4.2.4
Using actionpack 4.2.4
Using actionview 4.2.4
Using activejob 4.2.4
Using activemodel 4.2.4
Using activerecord 4.2.4
Using activesupport 4.2.4
Using acts-as-taggable-on 3.5.0
Using angular-rails-templates 0.2.0
Using angular_rails_csrf 1.0.4
Using arel 6.0.3
Using aws-sdk-v1 1.66.0
Using bcrypt 3.1.10
Using bower-rails 0.10.0
Using builder 3.2.2
Using bundler 1.10.6
Using capistrano 3.4.0
Using capistrano-bundler 1.1.4
Using capistrano-rails 1.1.3
Using capistrano-rvm 0.1.2
Using chronic 0.10.2
Using coffee-rails 4.1.0
Using coffee-script 2.4.1
Using coffee-script-source 1.9.1.1
Using cognac 0.2.1
Using colorize 0.7.7
Using devise 3.5.1
Using devise_token_auth 0.1.32
Using diff-lcs 1.2.5
Using erubis 2.7.0
Using execjs 2.6.0
Using factory_girl 4.5.0
Using factory_girl_rails 4.5.0
Using globalid 0.3.6
Using hashie 3.4.2
Using hike 1.2.3
Using i18n 0.7.0
Using jbuilder 2.3.2
Using jquery-rails 4.0.5
Using json 1.8.3
Using loofah 2.0.3
Using lyon 0.1.0
Using mail 2.6.3
Using mime-types 2.6.2
Using mini_portile 0.6.2
Using minitest 5.8.1
Using multi_json 1.11.2
Using mysql2 0.3.20
Using net-scp 1.2.1
Using net-ssh 3.0.1
Using nokogiri 1.6.6.2
Using omniauth 1.2.2
Using orm_adapter 0.5.0
Using rack 1.6.4
Using rack-test 0.6.3
Using rails 4.2.4
Using rails-deprecated_sanitizer 1.0.3
Using rails-dom-testing 1.0.7
Using rails-html-sanitizer 1.0.2
Using railties 4.2.4
Using rake 10.4.2
Using responders 2.1.0
Using rspec-core 3.3.2
Using rspec-expectations 3.3.1
Using rspec-mocks 3.3.2
Using rspec-rails 3.3.3
Using rspec-support 3.3.0
Using sass 3.4.18
Using sass-rails 5.0.4
Using simple_form 3.2.0
Using spring 1.4.0
Using sprockets 2.12.4
Using sprockets-rails 2.3.3
Using sshkit 1.7.1
Using thor 0.19.1
Using thread_safe 0.3.5
Using tilt 1.4.1
Using tld_length 1.0.0
Using tzinfo 1.2.2
Using uglifier 2.7.2
Using warden 1.2.3
Using whenever 0.9.4
Bundle complete! 27 Gemfile dependencies, 82 gems now installed.
Use bundle show [gemname] to see where a bundled gem is installed.

Started POST "/api/v1/auth/sign_in" for 127.0.0.1 at 2015-10-05 10:45:49 -0400
Processing by Api::V1::SessionsController#create as HTML
Parameters: {"email"=>"[email protected]", "password"=>"[FILTERED]", "remember_me"=>0, "session"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "remember_me"=>0}}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
actionpack (4.2.4) lib/action_controller/metal/request_forgery_protection.rb:181:in handle_unverified_request' actionpack (4.2.4) lib/action_controller/metal/request_forgery_protection.rb:209:inhandle_unverified_request'
devise (3.5.1) lib/devise/controllers/helpers.rb:251:in handle_unverified_request' actionpack (4.2.4) lib/action_controller/metal/request_forgery_protection.rb:204:inverify_authenticity_token'
activesupport (4.2.4) lib/active_support/callbacks.rb:432:in block in make_lambda' activesupport (4.2.4) lib/active_support/callbacks.rb:164:incall'
activesupport (4.2.4) lib/active_support/callbacks.rb:164:in block in halting' activesupport (4.2.4) lib/active_support/callbacks.rb:504:incall'
activesupport (4.2.4) lib/active_support/callbacks.rb:504:in block in call' activesupport (4.2.4) lib/active_support/callbacks.rb:504:ineach'
activesupport (4.2.4) lib/active_support/callbacks.rb:504:in call' activesupport (4.2.4) lib/active_support/callbacks.rb:92:inrun_callbacks'
activesupport (4.2.4) lib/active_support/callbacks.rb:778:in _run_process_action_callbacks' activesupport (4.2.4) lib/active_support/callbacks.rb:81:inrun_callbacks'
actionpack (4.2.4) lib/abstract_controller/callbacks.rb:19:in process_action' actionpack (4.2.4) lib/action_controller/metal/rescue.rb:29:inprocess_action'
actionpack (4.2.4) lib/action_controller/metal/instrumentation.rb:32:in block in process_action' activesupport (4.2.4) lib/active_support/notifications.rb:164:inblock in instrument'
activesupport (4.2.4) lib/active_support/notifications/instrumenter.rb:20:in instrument' activesupport (4.2.4) lib/active_support/notifications.rb:164:ininstrument'
actionpack (4.2.4) lib/action_controller/metal/instrumentation.rb:30:in process_action' actionpack (4.2.4) lib/action_controller/metal/params_wrapper.rb:250:inprocess_action'
activerecord (4.2.4) lib/active_record/railties/controller_runtime.rb:18:in process_action' actionpack (4.2.4) lib/abstract_controller/base.rb:137:inprocess'
actionview (4.2.4) lib/action_view/rendering.rb:30:in process' actionpack (4.2.4) lib/action_controller/metal.rb:196:indispatch'
actionpack (4.2.4) lib/action_controller/metal/rack_delegation.rb:13:in dispatch' actionpack (4.2.4) lib/action_controller/metal.rb:237:inblock in action'
actionpack (4.2.4) lib/action_dispatch/routing/route_set.rb:76:in call' actionpack (4.2.4) lib/action_dispatch/routing/route_set.rb:76:indispatch'
actionpack (4.2.4) lib/action_dispatch/routing/route_set.rb:45:in serve' actionpack (4.2.4) lib/action_dispatch/routing/mapper.rb:49:inserve'
actionpack (4.2.4) lib/action_dispatch/journey/router.rb:43:in block in serve' actionpack (4.2.4) lib/action_dispatch/journey/router.rb:30:ineach'
actionpack (4.2.4) lib/action_dispatch/journey/router.rb:30:in serve' actionpack (4.2.4) lib/action_dispatch/routing/route_set.rb:821:incall'
tld_length (1.0.0) lib/rack/tld_length.rb:16:in call' warden (1.2.3) lib/warden/manager.rb:35:inblock in call'
warden (1.2.3) lib/warden/manager.rb:34:in catch' warden (1.2.3) lib/warden/manager.rb:34:incall'
rack (1.6.4) lib/rack/etag.rb:24:in call' rack (1.6.4) lib/rack/conditionalget.rb:38:incall'
rack (1.6.4) lib/rack/head.rb:13:in call' actionpack (4.2.4) lib/action_dispatch/middleware/params_parser.rb:27:incall'
actionpack (4.2.4) lib/action_dispatch/middleware/flash.rb:260:in call' rack (1.6.4) lib/rack/session/abstract/id.rb:225:incontext'
rack (1.6.4) lib/rack/session/abstract/id.rb:220:in call' actionpack (4.2.4) lib/action_dispatch/middleware/cookies.rb:560:incall'
activerecord (4.2.4) lib/active_record/query_cache.rb:36:in call' activerecord (4.2.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:653:incall'
activerecord (4.2.4) lib/active_record/migration.rb:377:in call' actionpack (4.2.4) lib/action_dispatch/middleware/callbacks.rb:29:inblock in call'
activesupport (4.2.4) lib/active_support/callbacks.rb:88:in __run_callbacks__' activesupport (4.2.4) lib/active_support/callbacks.rb:778:in_run_call_callbacks'
activesupport (4.2.4) lib/active_support/callbacks.rb:81:in run_callbacks' actionpack (4.2.4) lib/action_dispatch/middleware/callbacks.rb:27:incall'
actionpack (4.2.4) lib/action_dispatch/middleware/reloader.rb:73:in call' actionpack (4.2.4) lib/action_dispatch/middleware/remote_ip.rb:78:incall'
actionpack (4.2.4) lib/action_dispatch/middleware/debug_exceptions.rb:17:in call' actionpack (4.2.4) lib/action_dispatch/middleware/show_exceptions.rb:30:incall'
railties (4.2.4) lib/rails/rack/logger.rb:38:in call_app' railties (4.2.4) lib/rails/rack/logger.rb:20:inblock in call'
activesupport (4.2.4) lib/active_support/tagged_logging.rb:68:in block in tagged' activesupport (4.2.4) lib/active_support/tagged_logging.rb:26:intagged'
activesupport (4.2.4) lib/active_support/tagged_logging.rb:68:in tagged' railties (4.2.4) lib/rails/rack/logger.rb:20:incall'
actionpack (4.2.4) lib/action_dispatch/middleware/request_id.rb:21:in call' rack (1.6.4) lib/rack/methodoverride.rb:22:incall'
rack (1.6.4) lib/rack/runtime.rb:18:in call' activesupport (4.2.4) lib/active_support/cache/strategy/local_cache_middleware.rb:28:incall'
rack (1.6.4) lib/rack/lock.rb:17:in call' actionpack (4.2.4) lib/action_dispatch/middleware/static.rb:116:incall'
rack (1.6.4) lib/rack/sendfile.rb:113:in call' railties (4.2.4) lib/rails/engine.rb:518:incall'
railties (4.2.4) lib/rails/application.rb:165:in call' rack (1.6.4) lib/rack/lock.rb:17:incall'
rack (1.6.4) lib/rack/content_length.rb:15:in call' rack (1.6.4) lib/rack/handler/webrick.rb:88:inservice'
/home/sburke/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/webrick/httpserver.rb:138:in service' /home/sburke/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/webrick/httpserver.rb:94:inrun'
/home/sburke/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/webrick/server.rb:294:in `block in start_thread'

Rendered /home/sburke/.rvm/gems/ruby-2.2.3@gdo20151004/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_source.erb (9.7ms)
Rendered /home/sburke/.rvm/gems/ruby-2.2.3@gdo20151004/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (4.0ms)
Rendered /home/sburke/.rvm/gems/ruby-2.2.3@gdo20151004/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.5ms)
Rendered /home/sburke/.rvm/gems/ruby-2.2.3@gdo20151004/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (53.4ms)

@tigarcia
Copy link

I've run into a very similar issue. I'm creating a single page app that has sign in and sign out. From what I can tell, devise signout deletes the CSRF token from the session which will in turn make all requests to your server fail if you have protect_from_forgery enabled. I've verified this by decrypting my session cookie and seeing that the CSRF token is no longer in the cookie after sign out. Doing a little searching, the solution seems to be to override the devise controller and return the new csrf token to your front end after signout:

http://stackoverflow.com/questions/11845500/rails-devise-authentication-csrf-issue

@sburke56
Copy link
Author

sburke56 commented Dec 4, 2015

Thanks for the link. I had some trouble with the suggestions in the link. Ultimately I wasn't able to get things working and rolled back. I posted my question here.

http://stackoverflow.com/questions/33902387/after-angular-logout-cant-verify-csrf-token-authenticity

@txssseal
Copy link

@sburke56, were you able to figure this out?

@sburke56
Copy link
Author

Yeah I was able to fix it. It was mainly a misunderstanding of the problem. Here's my comment in my code which is how I understood it.

  • As per the comment in application_controller.rb for json apis we
    need to use a null_session when the authenticity token can't be
    verified. This means it's not going to throw the exception any more
    and we also don't have to turn off the CSRF checking on all
    controllers or on a case by case basis which is what we were doing
    before.

application_controller.rb

# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :null_session

@muhammadn
Copy link

i had made a fix by creating directory in app/controllers/overrides (nothing to do with the controller override in devise_token_auth README) and add a file that i want to pass some code to the controllers with :null_session for only devise_token_auth parts of the code.

More info here:
https://github.com/lynndylanhurley/devise_token_auth#passing-blocks-controllers

For example:
I created a file called sessions_controller.rb in app/controllers/overrides and then add this code into it:

class Overrides::SessionsController < DeviseTokenAuth::SessionsController
  skip_before_action :protect_from_forgery
  protect_from_forgery with: :null_session
end

with this in my route

  namespace :api do
    scope :v1 do
      mount_devise_token_auth_for 'User', at: 'auth', controllers: {
        sessions: 'overrides/sessions'
      }
    end

It works perfectly - by default CSRF Token is used to validate form inputs however for devise_token_auth i can skip from using CSRF token and use null_session instead, all from the same app.

Credits: http://stackoverflow.com/questions/23673040/override-the-protect-from-forgery-strategy-in-a-controller

@guilhermeap
Copy link

protect_from_forgery with: :null_session, only: Proc.new { |c| c.request.format.json? }

@51koichi
Copy link

51koichi commented Aug 23, 2016

Add 「skip_before_filter :verify_authenticity_token」 to "application_controller.rb"
My case is NG「protect_from_forgery with: :null_session」

class ApplicationController < ActionController::Base
      include DeviseTokenAuth::Concerns::SetUserByToken
      before_filter :configure_permitted_parameters, if: :devise_controller?
      # protect_from_forgery with: :null_session
      skip_before_filter :verify_authenticity_token
end 

Have a good day!

@josephecombs
Copy link

josephecombs commented Jul 20, 2018

@guilhermeap - in what controller do you put that line? My configuration hits DeviseTokenAuth::SessionsController#create directly.

@fikrikarim
Copy link

@josephecombs in ApplicationController.rb works for me

@elthariel
Copy link

protect_from_forgery with: :null_session, only: Proc.new { |c| c.request.format.json? }

On newer rails versions:

protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format.json? }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants