Merge pull request #10049 from colinux/fix-params-i18n-sanitization

Tech: chiffre le param email réaffiché dans la vue pour éviter de construire des pages de phishing
This commit is contained in:
mfo 2024-02-28 14:17:47 +01:00 committed by GitHub
commit 43a9ee0ca4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 32 additions and 8 deletions

View file

@ -117,6 +117,10 @@ class ApplicationController < ActionController::Base
"window.location.href='#{path}'"
end
def message_verifier
@message_verifier ||= ActiveSupport::MessageVerifier.new(Rails.application.secret_key_base)
end
protected
def feature_enabled?(feature_name)
@ -282,7 +286,8 @@ class ApplicationController < ActionController::Base
end
send_login_token_or_bufferize(current_instructeur)
redirect_to link_sent_path(email: current_instructeur.email)
signed_email = message_verifier.generate(current_instructeur.email, purpose: :reset_link, expires_in: 1.hour)
redirect_to link_sent_path(email: signed_email)
end
end

View file

@ -26,7 +26,7 @@ class Users::PasswordsController < Devise::PasswordsController
# end
def reset_link_sent
@email = params[:email]
@email = message_verifier.verify(params[:email], purpose: :reset_password) rescue nil
end
protected
@ -37,7 +37,8 @@ class Users::PasswordsController < Devise::PasswordsController
def after_sending_reset_password_instructions_path_for(resource_name)
flash.discard(:notice)
users_password_reset_link_sent_path(email: resource.email)
signed_email = message_verifier.generate(resource.email, purpose: :reset_password, expires_in: 1.hour)
users_password_reset_link_sent_path(email: signed_email)
end
def try_to_authenticate_instructeur

View file

@ -25,12 +25,16 @@ class Users::SessionsController < Devise::SessionsController
if send_login_token_or_bufferize(current_instructeur)
flash[:notice] = "Nous venons de vous renvoyer un nouveau lien de connexion sécurisée à #{APPLICATION_NAME}"
end
redirect_to link_sent_path(email: current_instructeur.email)
signed_email = message_verifier.generate(current_instructeur.email, purpose: :reset_link, expires_in: 1.hour)
redirect_to link_sent_path(email: signed_email)
end
def link_sent
if StrictEmailValidator::REGEXP.match?(params[:email])
@email = params[:email]
email = message_verifier.verify(params[:email], purpose: :reset_link) rescue nil
if StrictEmailValidator::REGEXP.match?(email)
@email = email
else
redirect_to root_path
end

View file

@ -43,11 +43,23 @@ describe Users::PasswordsController, type: :controller do
let(:email) { 'test@example.com' }
it 'displays the page' do
get 'reset_link_sent', params: { email: email }
signed_email = controller.message_verifier.generate(email, purpose: :reset_password)
get 'reset_link_sent', params: { email: signed_email }
expect(response).to have_http_status(:ok)
expect(response).to render_template('reset_link_sent')
expect(assigns(:email)).to eq email
end
context 'when signed email is invalid' do
it "does not fail" do
get 'reset_link_sent', params: { email: "invalid.message" }
expect(response).to have_http_status(:ok)
expect(response).to render_template('reset_link_sent')
expect(assigns(:email)).to be_nil
end
end
end
end

View file

@ -225,7 +225,9 @@ describe Users::SessionsController, type: :controller do
describe '#link_sent' do
render_views
before { get :link_sent, params: { email: link_email } }
before { get :link_sent, params: { email: signed_email } }
let(:signed_email) { controller.message_verifier.generate(link_email, purpose: :reset_link) }
context 'when the email is legit' do
let(:link_email) { 'a@a.com' }