mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 10:31:13 -05:00
Fix: Implement emergency MFA security fix
This commit is contained in:
@@ -37,6 +37,7 @@ export default function Auth() {
|
||||
const [signInCaptchaToken, setSignInCaptchaToken] = useState<string | null>(null);
|
||||
const [signInCaptchaKey, setSignInCaptchaKey] = useState(0);
|
||||
const [mfaFactorId, setMfaFactorId] = useState<string | null>(null);
|
||||
const [mfaPendingEmail, setMfaPendingEmail] = useState<string | null>(null);
|
||||
|
||||
const emailParam = searchParams.get('email');
|
||||
const messageParam = searchParams.get('message');
|
||||
@@ -154,10 +155,17 @@ export default function Auth() {
|
||||
const totpFactor = factors?.totp?.find(f => f.status === 'verified');
|
||||
|
||||
if (totpFactor) {
|
||||
// Show MFA challenge
|
||||
// CRITICAL SECURITY FIX: IMMEDIATELY DESTROY THE AAL1 SESSION
|
||||
// The user MUST NOT have any active session before completing MFA
|
||||
console.log('[Auth] MFA required - destroying AAL1 session before challenge');
|
||||
await supabase.auth.signOut();
|
||||
|
||||
// Store email and factor ID in component state ONLY
|
||||
// At this point, user has NO authenticated session
|
||||
setMfaPendingEmail(formData.email);
|
||||
setMfaFactorId(totpFactor.id);
|
||||
setLoading(false);
|
||||
return; // Stay on page, show MFA modal
|
||||
return; // User has NO session - MFA modal will show
|
||||
} else {
|
||||
// MFA is required but no factor found - FORCE SIGN OUT for security
|
||||
console.error('[Auth] SECURITY: MFA required but no verified factor found');
|
||||
@@ -245,35 +253,9 @@ export default function Auth() {
|
||||
};
|
||||
|
||||
const handleMfaCancel = async () => {
|
||||
try {
|
||||
// CRITICAL SECURITY: Log cancellation attempt
|
||||
const { data: { session } } = await supabase.auth.getSession();
|
||||
if (session) {
|
||||
try {
|
||||
const { data: aalData } = await supabase.auth.mfa.getAuthenticatorAssuranceLevel();
|
||||
await supabase.rpc('log_admin_action', {
|
||||
_admin_user_id: session.user.id,
|
||||
_action: 'mfa_verification_cancelled',
|
||||
_target_user_id: session.user.id,
|
||||
_details: {
|
||||
timestamp: new Date().toISOString(),
|
||||
reason: 'user_cancelled_mfa_prompt',
|
||||
aal_before_cancel: aalData?.currentLevel || 'aal1'
|
||||
}
|
||||
});
|
||||
} catch (logError) {
|
||||
console.error('Failed to log MFA cancellation:', logError);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during MFA cancellation:', error);
|
||||
}
|
||||
|
||||
// CRITICAL SECURITY: User cannot bypass MFA if enrolled
|
||||
// Cancelling MFA prompt MUST sign the user out
|
||||
await supabase.auth.signOut();
|
||||
|
||||
// Clear state variables
|
||||
setMfaFactorId(null);
|
||||
setMfaPendingEmail(null);
|
||||
setSignInCaptchaKey(prev => prev + 1);
|
||||
|
||||
toast({
|
||||
|
||||
Reference in New Issue
Block a user