OTP/SMS/email for step-up on multi-device/web
Why it matters
Not all users have biometric hardware — older laptops, shared workstations, and most desktop web browsers lack TouchID or FaceID. If biometric is the only step-up path on multi-device or web contexts, users without capable hardware are either blocked from completing financial operations or silently bypassed by the application. CWE-308 (Use of Single-Factor Authentication) applies when a required step-up factor is unavailable to a meaningful portion of users. PCI-DSS Req 8.4 requires that multi-factor authentication be available for all applicable users. At least two fallback methods — OTP-SMS, OTP-email, or TOTP — ensures step-up is universally enforced rather than selectively applied based on hardware.
Severity rationale
Low because users without biometric hardware on multi-device contexts lose step-up protection entirely, effectively removing an authentication control for a predictable subset of the user population.
Remediation
Add OTP and TOTP fallback paths in src/lib/stepUpAuth.ts for multi-device and web contexts:
export async function performMultiDeviceStepUp(
email: string,
phone: string
): Promise<boolean> {
const method = await promptStepUpMethod(
['otp-sms', 'otp-email', 'totp-app']
);
if (method === 'otp-sms') {
const otp = generateOTP();
await sendSMS(phone, `Your verification code: ${otp}`);
return verifyOTP(otp);
}
if (method === 'otp-email') {
const otp = generateOTP();
await sendEmail(email, `Your verification code: ${otp}`);
return verifyOTP(otp);
}
if (method === 'totp-app') {
return verifyTOTP(); // TOTP authenticator app
}
return false;
}
Expose at minimum two of the three methods so a user without a phone can use email OTP, and a user without email access can use a TOTP app.
Detection
- ID:
otp-sms-email-multidevice - Severity:
low - What to look for: Count all step-up authentication methods available on multi-device/web contexts. Enumerate each method (OTP-SMS, OTP-email, TOTP app, password re-entry). Quote the actual method options found. Verify at least 2 fallback methods exist for users without biometric hardware.
- Pass criteria: On multi-device or web contexts, at least 2 step-up authentication methods are available (e.g., OTP-SMS + OTP-email, or TOTP + password re-entry). Report the count even on pass (e.g., "3 step-up methods on web: OTP-SMS, OTP-email, TOTP app").
- Fail criteria: Multi-device step-up relies only on biometric with fewer than 2 fallback methods, or 0 step-up methods available on web.
- Skip (N/A) when: The application does not support multi-device scenarios — cite the actual device support found.
- Detail on fail:
"1 of 2 required step-up methods on web — only WebAuthn, 0 OTP fallbacks for users without biometric hardware" - Remediation: Implement OTP step-up for multi-device contexts (in
src/lib/stepUpAuth.ts):// lib/stepUpAuth.ts export async function performMultiDeviceStepUp(email: string, phone: string) { const method = await promptStepUpMethod(['otp-sms', 'otp-email', 'totp-app']); if (method === 'otp-sms') { const otp = generateOTP(); await sendSMS(phone, `Your step-up code: ${otp}`); return await verifyOTP(otp); } else if (method === 'otp-email') { const otp = generateOTP(); await sendEmail(email, `Your step-up code: ${otp}`); return await verifyOTP(otp); } else if (method === 'totp-app') { return await verifyTOTP(); // Authenticator app } }
External references
- cwe · CWE-308 — Use of Single-factor Authentication
- owasp:2021 · A07
- pci-dss:4.0 · Req 8.4 — MFA for non-console administrative access and CDE access
Taxons
History
- 2026-04-18·v1.0.0·Initial import from finserv-session-security·automated