Skip to content

VOL 08 / CH 03 / LESSON 01

3.1 User Authentication: Passwords, Passkeys, Sessions, and Account Recovery ​

Authentication answers the question: "Who is making this request, and how certain can we be about that identity?" The login page is just the entry point; registration, authenticator binding, session continuity, re-authentication, account recovery, and logout together form the full user lifecycle. The weakest link is often not the login mechanism itself, but the recovery process or customer support bypasses.

The Number of Factors Does Not Equal the Number of Fields ​

Authentication factors are categorized by their source:

text
something you know: passwords, PINs
something you have: security keys, devices holding private keys
something you are: biometrics

A password combined with a security question still counts as two "something you know" factors and does not constitute multi-factor authentication (MFA). Local device fingerprint recognition (such as on a smartphone) is typically used to unlock a private key stored on the device. The server receives a cryptographic signature, not the user's raw fingerprint template, and should never store the original biometric data.

One-time passwords (OTPs) can resist simple password reuse but can be immediately forwarded by phishing sites. NIST does not consider manually entered OTPs to be phishing-resistant. For high-risk systems, it is recommended to provide authentication mechanisms based on public-key cryptography and bound to the verifier’s identity, such as a correctly implemented WebAuthn/passkey.

Passkeys Are Public-Key Credentials Scoped to an RP ​

During registration, the authenticator generates a key pair for the relying party (RP), and the server validates the registration response before storing the public key and credential metadata. Authentication uses a fresh random challenge; the authenticator signs authenticatorData || SHA-256(clientDataJSON). The RP ID hash is in authenticator data; the challenge and origin are in client data.

text
Registration: challenge → authenticator creates key pair → store public key
Authentication: fresh challenge → scoped signature → verify signature, challenge, origin, RP and flags

The private key is never sent to the server. Credentials are scoped by RP ID, so an unrelated phishing domain cannot obtain an assertion for the real site when the browser enforces RP ID scoping and the server validates origin. Passkeys can be device-bound or synchronized through an end-to-end encrypted platform service; risk models must distinguish between scenarios like account recovery via synchronization, device unlocking, and hardware attestation, rather than treating all passkeys as equivalent in terms of security assurance.

Use a maintained WebAuthn library to check response type, signature, one-time challenge, allowed origins, RP ID hash, and account/credential binding and status. User presence (UP) is not user verification (UV): when PIN or biometric verification is required, request and check UV rather than merely accepting a button press. signCount is a cloning-risk signal. Some authenticators always return 0, and synchronized credentials should not be assumed to have a cross-device monotonic counter. It does not replace one-time challenge validation. Attestation may introduce device identifiability and vendor dependency; it should only be required when a clear need for device origin verification exists.

Passwords Still Require System-Level Design ​

When implementing passwords, integrate them with the Argon2id storage pattern from Lesson 1.2 and ensure the following:

  • Support long passwords, password manager-generated credentials, and clipboard pasting;
  • Enforce blocking of common and known-compromised passwords via a blocklist;
  • Implement rate limiting stratified by account, origin, device, and global risk levels;
  • Return a unified login error message to prevent account enumeration;
  • Trigger step-up authentication for high-risk logins instead of permanently locking accounts or creating denial-of-service conditions;
  • Send auditable notifications for login attempts, account recovery, and authentication method changes.

Periodic forced password changes can encourage predictable patterns like Spring2026!. Instead, mandate password resets only in response to detected breaches, sharing, or risk events, and invalidate associated sessions in those cases.

Session Cookies Are Opaque Handles in the Browser ​

Server-side sessions are generally easier to revoke and update than storing full authorization state in a JWT sent to the browser:

text
Cookie: __Host-session=<high-entropy opaque id>
Server store: id → subject, auth_time, assurance, expiry, device, revocation

After successful authentication or a change in assurance or privilege level, issue a new session ID and invalidate the old one to prevent session fixation. Sensitive operations need recent-authentication checks; rotating the ID on every sensitive request is not a universal requirement. Cookies are typically configured with:

http
Set-Cookie: __Host-session=...; Secure; HttpOnly; SameSite=Lax; Path=/

Secure requires HTTPS, HttpOnly prevents ordinary scripts from reading the cookie, and SameSite reduces some cross-site request risks. The __Host- prefix requires Secure, Path=/, and no Domain attribute, reducing parent/subdomain cookie-scope confusion. HttpOnly does not stop XSS from sending requests as the current user. These measures do not replace output encoding, Content Security Policy (CSP), or full CSRF protection; threat models can still change with same-site subdomains, top-level navigation, or business-critical cross-site flows.

Sessions must have both idle and absolute timeouts. For sensitive operations, the most recent authentication time should be checked, and re-authentication or stronger authentication factors required. Logout must invalidate the server-side state, rather than remove the browser cookie alone. When users change passwords or authentication devices, they should be notified and given the ability to revoke sessions on other devices.

CSRF Exploits the Browser's Automatic Credential Sending ​

If browsers automatically send session cookies, attackers can trick users into visiting malicious pages that then make requests to legitimate sites. Common defenses include:

  • Preventing GET requests from causing state changes;
  • Using unpredictable, session-bound CSRF tokens;
  • Validating Origin or Referer headers as an additional layer of protection;
  • Setting SameSite attributes appropriately;
  • Requiring re-authentication or transaction confirmation for high-risk actions.

CORS is not a CSRF mitigation technique. It primarily restricts malicious pages from reading responses, and simple form submissions can still be sent.

Recovery Flow Determines True Account Strength ​

If customer service can remove a passkey using just a name and birthday, the security benefits of hardware authentication are bypassed. When designing recovery workflows, consider:

  1. Pre-register multiple independent authenticators and one-time recovery codes;
  2. Show recovery codes once and store one-way verifiers: low-entropy codes need salted password hashing; sufficiently high-entropy random codes can use an appropriate cryptographic hash. Limit online attempts;
  3. For high-value accounts, implement delayed verification, notifications, and multiple independent sources of evidence;
  4. After recovery, terminate old sessions and high-risk tokens;
  5. Maintain audit trails and revocation windows for new authenticator bindings and changes to email or phone number;
  6. Support personnel must not see or request passwords, OTPs, or recovery codes. Verification and consumption of a one-time code must be atomic.

Test at least these failures: the old session ID is rejected after login; replaying a cookie fails after logout; an assertion from another origin is rejected; only one consumption of a challenge or recovery code succeeds; missing required UV cannot earn the same assurance level. After recovery resets a password, verify that old sessions and bound credentials retire as policy requires.

Authentication is not simply "login success = true." Applications must record authentication timestamps, methods, assurance levels, and risk context to support future authorization decisions and step-up authentication requirements.

Continue with OAuth 2.0 and OpenID Connect for delegated authorization and authentication results.

References ​

Built with VitePress | Software Systems Atlas