Fix csrf cleanup for Rails 7.1 (main)

Rails implemented a CSRF token storage strategy to allow storing the
CSRF tokens outside of the sessios (for example, in an encrypted
cookie), and changed how the value is kept around during the request
cycle, by using a request.env value.

We still want to ensure the final session value is cleaned correctly in
the test, but the implementation needed to change since we can't simply
delete from the session anymore, we need to make sure we call the Rails
methods for resetting the current storage strategy so it works with all
of them.

https://github.com/rails/rails/pull/44283
This commit is contained in:
Carlos Antonio da Silva 2022-04-22 10:41:01 -03:00
parent e1c53d6580
commit b5172a0cdb
2 changed files with 17 additions and 3 deletions

View File

@ -4,6 +4,12 @@ Warden::Manager.after_authentication do |record, warden, options|
clean_up_for_winning_strategy = !warden.winning_strategy.respond_to?(:clean_up_csrf?) ||
warden.winning_strategy.clean_up_csrf?
if Devise.clean_up_csrf_token_on_authentication && clean_up_for_winning_strategy
warden.request.session.try(:delete, :_csrf_token)
request = warden.request
if request.respond_to?(:controller_instance) && request.controller_instance.respond_to?(:reset_csrf_token)
# Rails 7.1+
request.controller_instance.reset_csrf_token(request)
else
request.session.try(:delete, :_csrf_token)
end
end
end

View File

@ -346,10 +346,18 @@ class AuthenticationSessionTest < Devise::IntegrationTest
test 'refreshes _csrf_token' do
swap ApplicationController, allow_forgery_protection: true do
get new_user_session_path
token = request.session[:_csrf_token]
token_from_session = request.session[:_csrf_token]
if Devise::Test.rails71_and_up?
token_from_env = request.env["action_controller.csrf_token"]
end
sign_in_as_user
assert_not_equal request.session[:_csrf_token], token
assert_not_equal request.session[:_csrf_token], token_from_session
if Devise::Test.rails71_and_up?
assert_not_equal request.env["action_controller.csrf_token"], token_from_env
end
end
end