Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ def redirect_to_signin
analytics.invalid_authenticity_token(controller: controller_info)
sign_out
flash[:error] = t('errors.general')
redirect_back fallback_location: new_user_session_url, allow_other_host: false
begin
redirect_back fallback_location: new_user_session_url, allow_other_host: false
rescue ActionController::Redirecting::UnsafeRedirectError => err
# Exceptions raised inside exception handlers are not propagated up, so we manually rescue
unsafe_redirect_error(err)
end
end

def check_user_needs_redirect
Expand Down Expand Up @@ -228,4 +233,16 @@ def override_csp_for_google_analytics
request.content_security_policy = policy
end
end

def unsafe_redirect_error(_exception)
controller_info = "#{controller_path}##{action_name}"
analytics.unsafe_redirect_error(
controller: controller_info,
user_signed_in: user_signed_in?,
referer: request.referer,
)

flash[:error] = t('errors.general')
redirect_to new_user_session_url
end
end
20 changes: 20 additions & 0 deletions spec/controllers/users/sessions_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,26 @@
expect(flash[:error]).to eq t('errors.general')
end

it 'redirects back to home page if CSRF error and referer is invalid' do
user = create(:user, :signed_up)
stub_analytics
analytics_hash = { controller: 'users/sessions#create', user_signed_in: nil }
allow(controller).to receive(:create).and_raise(ActionController::InvalidAuthenticityToken)

expect(@analytics).to receive(:track_event).
with('Invalid Authenticity Token', analytics_hash)

expect(@analytics).to receive(:track_event).
with('Unsafe Redirect', { controller: 'users/sessions#create', referer: '@@@',
user_signed_in: false })

request.env['HTTP_REFERER'] = '@@@'
post :create, params: { user: { email: user.email, password: user.password } }

expect(response).to redirect_to new_user_session_url
expect(flash[:error]).to eq t('errors.general')
end

it 'returns to sign in page if email is a Hash' do
post :create, params: { user: { email: { foo: 'bar' }, password: 'password' } }

Expand Down