Multi-Factor Authentication (MFA)
Multi-factor authentication requires a second proof of identity beyond the password — a code from your phone, a tap on a prompt, a hardware key. The idea: factors from different categories (something you know, something you have, something you are) fail independently, so a stolen password alone no longer opens the account.
The impact is enormous — Microsoft's telemetry famously put MFA at blocking the overwhelming majority of automated account-compromise attacks — but not uniform: factor choice matters. SMS codes stop bulk credential-stuffing yet fall to targeted phishing and SIM swaps, while passkeys and security keys resist even real-time phishing kits. Building MFA well means picking factors, fallbacks, and enforcement deliberately.
TL;DR
- MFA = requiring proofs from independent factor categories: knowledge (password/PIN), possession (phone, security key), inherence (biometric).
- Factor hierarchy, weakest → strongest: SMS/email codes → TOTP apps → push prompts (with number matching) → passkeys/security keys.
- Phishing resistance is the dividing line: OTP codes can be relayed by proxy-phishing kits in real time; WebAuthn credentials can't be — they're origin-bound.
- Implementing TOTP is straightforward: a shared secret (QR code), RFC 6238 code verification with a ±1 window, rate limiting, and single-use backup codes.
- Recovery is where MFA breaks: attackers target the reset/fallback path, and support-desk social engineering bypasses everything the login screen enforces.
- Use step-up authentication — re-prompt for a strong factor on sensitive actions — instead of treating MFA as a login-only gate.
The Factors Compared
Two attack patterns define the modern ranking:
- Adversary-in-the-middle phishing kits (Evilginx-style) proxy the real site, capture the password and the OTP the user types, and replay both instantly. Every "type a code" factor falls to this; WebAuthn doesn't, because the browser binds the signature to the real origin.
- MFA fatigue: flood a user with push prompts at 2 a.m. until one gets approved (how Uber was breached in 2022). Mitigation: number matching (the login screen shows "47", the phone asks you to enter it) and prompt rate limits.
Practical guidance: offer TOTP as the floor, push with number matching as the mainstream default, and passkeys/security keys as the strong path — and mandate the strong path for admins and privileged roles.
Implementing TOTP
TOTP remains the most widely implemented second factor. The pieces:
Enrollment
Verification
Non-negotiables around that check:
- Rate limit hard (a 6-digit code is 10⁶ guesses — trivial without throttling; lock or back off after ~5 failures). See Rate Limiting.
- Prevent replay: remember the last accepted time-step per user; never accept the same code twice.
- Encrypt stored secrets — a database leak of TOTP secrets silently disables MFA for everyone. See Secrets Management and Encryption.
Backup Codes
Generate ~10 single-use random codes at enrollment; store hashed (like passwords); cross out on use; let users regenerate. These are the sanctioned answer to "lost my phone" — far safer than weakening the reset flow.
Design Patterns
Step-Up Authentication
Rather than one gate at login, re-verify a strong factor at moments of consequence:
This bounds the damage of session theft — a stolen cookie can browse, but can't re-point the payout account. Mark sessions with the time and strength of the last verification.
Remember This Device
Re-prompting every login drives users to disable MFA. A signed, device-bound "trusted device" cookie (30–90 days) keeps friction where the risk is: new devices, new locations, sensitive actions.
Enforcement Rollout
For a SaaS product: make MFA available to all, enforceable per-organization by admins (an enterprise checkbox as standard as SSO), and mandatory for your own staff and privileged accounts. When SSO is in play, MFA enforcement usually belongs at the identity provider, once, for every app behind it.
The Recovery Problem
MFA's real-world failure mode is rarely the cryptography — it's the fallback:
- Reset flows: if "lost my authenticator" leads to an email link with no additional checks, email compromise defeats MFA entirely. Recovery should require more scrutiny than login — backup codes, a second registered factor, waiting periods, or identity verification for high-value accounts.
- Support desks: "Hi, I'm Alice, I got a new phone" defeats any protocol if the helpdesk resets MFA on a friendly voice (the 2023 MGM breach in one sentence). Script and gate support-initiated resets.
- Factor removal: adding or removing a factor should itself require step-up verification and trigger a notification to the account's contacts.
Design rule: enumerate every path that ends in "and then the attacker is in without the second factor" — that list, not the login form, is your MFA threat model.
Common Mistakes
Offering Only SMS
SMS is better than single-factor but is the weakest link available — SIM-swap attacks against valuable accounts are routine. Fine as one option for breadth; wrong as the ceiling.
No Rate Limiting on Code Entry
Six digits without throttling is brute-forceable in hours. This exact bug has produced real-world full MFA bypasses.
Verifying Enrollment Later (or Never)
Activating TOTP without confirming one code, or leaving half-enrolled states, generates lockouts and support load — which pressures the org into weak recovery, which becomes the vulnerability.
Treating MFA as Done at Login
Session cookies get stolen (infostealers, XSS). Without step-up on sensitive actions and short re-auth windows for admin surfaces, MFA protects the front door of a house with open windows.
Letting Users Skip Backup Codes
The user who skips backup-code setup is the ticket, the angry tweet, and the social-engineering vector six months later. Force acknowledgment at enrollment.
FAQ
MFA vs 2FA — different things?
2FA is MFA with exactly two factors; MFA is the general term. Colloquially they're interchangeable. The count matters less than the independence and strength of the factors — password + security question is two knowledge factors, i.e., not really MFA.
Are passkeys MFA?
Functionally yes: a passkey combines possession (the device holding the key) with inherence or knowledge (biometric/PIN unlock) in one step. Many compliance frameworks now recognize passkeys as satisfying MFA on their own — which is why "passkey instead of password+code" is the direction of travel.
Should I build TOTP myself or use a provider?
The TOTP math is a solved library problem (otplib, pyotp, etc.) — building it is reasonable. What providers (Auth0/Okta CIC, Stytch, Firebase Auth, or your SSO IdP) really sell is the surrounding machinery: enrollment UX, recovery flows, device trust, fraud signals. Small teams usually come out ahead buying.
Does MFA stop phishing?
Code-based MFA stops credential-stuffing and casual phishing, but not real-time proxy phishing — the kit forwards your code as fast as you type it. Only origin-bound factors (WebAuthn passkeys/security keys) are phishing-resistant. For admin and high-value accounts, that distinction should be policy.
What should trigger step-up authentication?
Money movement, credential/factor changes, email/phone changes, org-level destructive actions, new-device sensitive access, and support-initiated changes. Anything an attacker with a hijacked session would do first.
Related Topics
- Passkeys & WebAuthn — The phishing-resistant end state
- Authentication — Sessions and login architecture
- Password Security — The first factor done right
- SSO — Enforcing MFA centrally at the IdP
- Rate Limiting — The control that keeps OTPs meaningful
- Secrets Management — Protecting stored TOTP seeds