Implementing Multi-Factor Authentication (MFA)

1. Understanding MFA Factors

FactorTypeExample
KnowledgeSomething you knowPassword, PIN, security question
PossessionSomething you havePhone, hardware key, smart card
InherenceSomething you areFingerprint, face, voice
LocationSomewhere you areIP geo, GPS, network
BehaviorSomething you doTyping pattern, gait
Note: True MFA requires factors from different categories (e.g., password + phone, not password + security question).

2. Implementing SMS-Based OTP

AspectDetail
Code length6 digits
Validity5–10 min
Rate limit1 send / 60 sec, 5 / hour
Verification attempts5 max per code
ProviderTwilio, AWS SNS, Vonage
RiskSIM swap — NIST deprecated SMS for high-assurance

3. Implementing Email-Based OTP

AspectDetail
Code length6–8 digits or token link
Validity10–15 min
RiskOnly as strong as user's email account
DeliverabilitySPF/DKIM/DMARC configured

4. Using Time-Based OTP

Example: TOTP (RFC 6238) generation

import { authenticator } from "otplib";
const secret = authenticator.generateSecret();  // base32, 160 bits
const uri = authenticator.keyuri(user.email, "Acme", secret);
// Show QR code of uri to user

// Verify
const ok = authenticator.verify({ token: userInput, secret });
ParameterDefault
AlgorithmHMAC-SHA1
Digits6
Period30 sec
Window±1 step (clock skew)

5. Implementing Authenticator Apps

AppNotes
Google AuthenticatorCloud-sync since 2023
Microsoft AuthenticatorPush notifications + TOTP
AuthyMulti-device, encrypted backup
1Password / BitwardenBuilt into password managers
Provisioning URIotpauth://totp/Issuer:user?secret=...&issuer=...

6. Using Hardware Tokens

TokenStandardPhish-Resistant?
YubiKeyFIDO2 / WebAuthn / U2F / OTPYes (FIDO2)
Titan KeyFIDO2 / U2FYes
RSA SecurIDOTPNo
Smart Card (PIV)X.509Yes

7. Implementing Biometric Authentication

PlatformAPI
iOSLocalAuthentication / Face ID, Touch ID
AndroidBiometricPrompt
WebWebAuthn (platform authenticator)
WindowsWindows Hello

8. Implementing Push Notifications

Push MFA Flow

  1. User submits password → backend issues challenge ID
  2. Push notification sent to registered device
  3. User taps Approve / Deny in app (biometric optional)
  4. App signs challenge with device key → posts to server
  5. Server verifies signature → completes auth
  6. Display number-matching code to prevent fatigue attacks
Warning: Plain "approve" push prompts are vulnerable to MFA fatigue. Use number matching (user enters/confirms 2-digit code shown on login screen).

9. Setting Up Backup Codes

AspectDetail
Count8–10 codes
Format10-char alphanumeric (e.g., x7k9-p4m2-q1n8)
StorageHashed (bcrypt/argon2) — not retrievable
UseSingle-use, mark consumed on success
RegenerateInvalidate all on regen

10. Enforcing MFA Policies

PolicyTrigger
RequiredAll users (highest assurance)
Risk-basedNew device, suspicious IP
Role-basedAdmins always, others optional
Resource-basedStep-up for sensitive endpoints
Grace period14 days to enroll after signup

11. Implementing Step-Up Authentication

Example: ACR-based step-up (OIDC)

// Sensitive endpoint requires stronger AuthN
app.delete("/account", (req, res, next) => {
  if (req.user.acr !== "urn:mfa:phishing-resistant") {
    return res.status(401).json({
      error: "insufficient_authentication",
      acr_values: "urn:mfa:phishing-resistant",
      max_age: 300                  // require recent auth
    });
  }
  next();
});

12. Handling MFA Enrollment Flow

TOTP Enrollment

  1. User initiates "Enable 2FA"
  2. Server generates secret + QR code (provisional, NOT yet saved as enrolled)
  3. User scans QR in authenticator app
  4. User enters current TOTP code to confirm
  5. Server verifies code → marks MFA enabled, generates backup codes
  6. Display backup codes ONCE → user must save/print
  7. Send confirmation email