Multifactor authentication (MFA) protects a login by requiring two or more forms of identification. A typical web login combines a username and password with another proof that an attacker is less likely to possess. MFA is a strong defense for authentication systems, but the extra step must be usable by the people who need access. section 8.9
Common second factors include:
- A passcode sent by text message to a phone number the user can access. section 8.9
- A code from a previously synchronized authenticator app. section 8.9
- Approval of a push notification in a smartphone app. section 8.9
- Biometric proof, such as fingerprint or facial recognition. section 8.9
Choose the factor with the attack path in mind. SMS passcodes can be undermined when attackers clone phones or obtain phone numbers through social engineering. Authenticator apps avoid SMS costs and commonly generate time-based one-time passwords (TOTP): usually six-digit codes that refresh every 30 seconds. Validation depends on the application and authenticator sharing a secret seed. section 8.9
Do not make a technically strong factor an accessibility barrier. Some users lack phone numbers, smartphones, or biometric-capable devices. Offering MFA as an option can fit broad user populations, while enforcing it for systems that require higher security. Keep an alternative MFA method available when a preferred device capability is unavailable. section 8.9 section 8.10
Biometric MFA can use WebAuthn in the browser. The biometric data remains on the user’s device; it unlocks a token sent to the server for identity verification. During credential creation, generate a fresh, strongly random server challenge. A different unguessable challenge each time prevents replay of initialization to forge credentials. Use a stable user identifier rather than a username or email address that may change. section 8.10
if (typeof(PublicKeyCredential) == "undefined") { #1
throw new Error('Web Authentication API not supported.');
}
let credential = navigator.credentials.create({
publicKey: {
challenge: new Uint8Array([/*
server challenge here
*/]), #2
rp: {
name: 'Example Website', #3
},
user: {
id: new Uint8Array([/* user ID here */]), #4
name: 'exampleuser@example.com',
displayName: 'Example User',
},
authenticatorSelection: {
authenticatorAttachment: 'platform', #5
userVerification: 'required',
},
pubKeyCredParams: [
{type: 'public-key', alg: -7. },
{type: 'public-key', alg: -257},
],
timeout: 60000,
attestation: 'direct',
},
});
This credential-creation example checks for WebAuthn support, supplies a server challenge and stable user ID, and requires platform user verification. Platform selection lets the device and user choose an available biometric method. section 8.10
MFA complements, rather than replaces, other login protections. Use strong hashed password storage, rate limiting for incorrect guesses, and CAPTCHA protection for brute-force attacks. Where appropriate, OAuth or SAML single sign-on can place credential storage with a trusted identity provider. Prefer biometrics where practical; authenticator apps remain a good option, while SMS is comparatively flawed and costly. section 8.17








