Fix authentication failures after going halfway through a sign-in attempt (#16607)
* Add tests * Add security-related tests My first (unpublished) attempt at fixing the issues introduced (extremely hard-to-exploit) security vulnerabilities, addressing them in a test. * Fix authentication failures after going halfway through a sign-in attempt * Refactor `authenticate_with_sign_in_token` and `authenticate_with_two_factor` to make the two authentication steps more obvious
This commit is contained in:
@ -58,16 +58,20 @@ class Auth::SessionsController < Devise::SessionsController
|
||||
protected
|
||||
|
||||
def find_user
|
||||
if session[:attempt_user_id]
|
||||
if user_params[:email].present?
|
||||
find_user_from_params
|
||||
elsif session[:attempt_user_id]
|
||||
User.find_by(id: session[:attempt_user_id])
|
||||
else
|
||||
user = User.authenticate_with_ldap(user_params) if Devise.ldap_authentication
|
||||
user ||= User.authenticate_with_pam(user_params) if Devise.pam_authentication
|
||||
user ||= User.find_for_authentication(email: user_params[:email])
|
||||
user
|
||||
end
|
||||
end
|
||||
|
||||
def find_user_from_params
|
||||
user = User.authenticate_with_ldap(user_params) if Devise.ldap_authentication
|
||||
user ||= User.authenticate_with_pam(user_params) if Devise.pam_authentication
|
||||
user ||= User.find_for_authentication(email: user_params[:email])
|
||||
user
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:email, :password, :otp_attempt, :sign_in_token_attempt, credential: {})
|
||||
end
|
||||
|
@ -16,14 +16,18 @@ module SignInTokenAuthenticationConcern
|
||||
end
|
||||
|
||||
def authenticate_with_sign_in_token
|
||||
user = self.resource = find_user
|
||||
if user_params[:email].present?
|
||||
user = self.resource = find_user_from_params
|
||||
prompt_for_sign_in_token(user) if user&.external_or_valid_password?(user_params[:password])
|
||||
elsif session[:attempt_user_id]
|
||||
user = self.resource = User.find_by(id: session[:attempt_user_id])
|
||||
return if user.nil?
|
||||
|
||||
if user.present? && session[:attempt_user_id].present? && session[:attempt_user_updated_at] != user.updated_at.to_s
|
||||
restart_session
|
||||
elsif user_params.key?(:sign_in_token_attempt) && session[:attempt_user_id]
|
||||
authenticate_with_sign_in_token_attempt(user)
|
||||
elsif user.present? && user.external_or_valid_password?(user_params[:password])
|
||||
prompt_for_sign_in_token(user)
|
||||
if session[:attempt_user_updated_at] != user.updated_at.to_s
|
||||
restart_session
|
||||
elsif user_params.key?(:sign_in_token_attempt)
|
||||
authenticate_with_sign_in_token_attempt(user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -35,16 +35,20 @@ module TwoFactorAuthenticationConcern
|
||||
end
|
||||
|
||||
def authenticate_with_two_factor
|
||||
user = self.resource = find_user
|
||||
if user_params[:email].present?
|
||||
user = self.resource = find_user_from_params
|
||||
prompt_for_two_factor(user) if user&.external_or_valid_password?(user_params[:password])
|
||||
elsif session[:attempt_user_id]
|
||||
user = self.resource = User.find_by(id: session[:attempt_user_id])
|
||||
return if user.nil?
|
||||
|
||||
if user.present? && session[:attempt_user_id].present? && session[:attempt_user_updated_at] != user.updated_at.to_s
|
||||
restart_session
|
||||
elsif user.webauthn_enabled? && user_params.key?(:credential) && session[:attempt_user_id]
|
||||
authenticate_with_two_factor_via_webauthn(user)
|
||||
elsif user_params.key?(:otp_attempt) && session[:attempt_user_id]
|
||||
authenticate_with_two_factor_via_otp(user)
|
||||
elsif user.present? && user.external_or_valid_password?(user_params[:password])
|
||||
prompt_for_two_factor(user)
|
||||
if session[:attempt_user_updated_at] != user.updated_at.to_s
|
||||
restart_session
|
||||
elsif user.webauthn_enabled? && user_params.key?(:credential)
|
||||
authenticate_with_two_factor_via_webauthn(user)
|
||||
elsif user_params.key?(:otp_attempt)
|
||||
authenticate_with_two_factor_via_otp(user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Reference in New Issue
Block a user