Classroom Public page

SEC-101 Week 6: Authentication and Authorization

1,294 words

Passwords (storage discipline: salt + slow KDF). MFA (TOTP, WebAuthn/passkeys). Session management. OAuth 2.0/OIDC at conceptual depth. JWTs as credentials. Lab 5: Broken-auth lab walk on OWASP Juice Shop.


Reading (~30 min)

Read the OWASP Authentication Cheat Sheet (owasp.org/cheatsheets/Authentication_Cheat_Sheet). Focus on the sections on session management and the broken-authentication failure modes. Then read the JWT Security Best Practices page from auth0.com or a similar developer resource (search "JWT security best practices"). Notice how many of the JWT pitfalls come from the "alg=none" attack or from not validating the signature correctly.


Lecture outline (~1.5 hr)

Part 1: Authentication vs. authorization (15 min)

Two words that are consistently confused, with serious consequences when they are.

Authentication answers "who are you?" It is the process of verifying that someone is who they claim to be. A correct password, a valid TOTP code, a hardware token, a fingerprint: all are authentication factors.

Authorization answers "what are you allowed to do?" It is the process of checking whether an authenticated identity has permission to perform an action. An authenticated user cannot read another user's private data unless they are also authorized.

Access control is the enforcement of authorization: the mechanism that actually prevents the unauthorized action. An authorization policy that exists but is not enforced (client-side check only, missing server-side check) is the same failure mode covered in Week 3.

The common mistake: conflating the two. A system that asks "is the user logged in?" before every action is checking authentication. It should also ask "is this user allowed to perform this specific action on this specific resource?" Missing the second check is Broken Access Control (OWASP A01).

Part 2: Password storage (done correctly) (15 min)

Covered in depth in Week 5. Brief review for this week's context:

  • Salt + slow KDF (bcrypt, argon2id). Never fast hashes. Never unsalted.
  • The argon2id parameters for new deployments: 64 MB memory, 3 iterations, 4 threads (from RFC 9106 Section 4). Adjust based on your server's tolerable latency budget.
  • Never store passwords in plaintext. Never transmit passwords in plaintext (use TLS).
  • Never log passwords, even "for debugging."

Part 3: Multi-factor authentication (25 min)

A factor is one of: something you know (password, PIN), something you have (TOTP app, hardware token), something you are (biometric). MFA requires at least two different factors.

TOTP (Time-based One-Time Passwords, RFC 6238):

The authenticator app (Google Authenticator, Authy, 1Password, etc.) and the server share a secret. Both compute HMAC-SHA-1(secret, floor(time / 30)) and take the last 6 digits. The result changes every 30 seconds. An attacker who steals the password cannot log in without also controlling the TOTP app.

TOTP does not protect against real-time phishing: if an attacker tricks the user into entering both password and TOTP into a fake login page, the attacker can relay both to the real server within the 30-second window. This is an active attack; TOTP defeats passive credential-stuffing (using a leaked password list) but not real-time relay.

WebAuthn and passkeys (FIDO2):

WebAuthn uses public-key cryptography for authentication. The authenticator (a hardware key like a YubiKey, or the phone's secure enclave) generates a key pair per site. The public key is registered with the site; the private key never leaves the authenticator. Signing is tied to the site's origin, so a phishing site at fake-bank.com cannot receive a valid signature for real-bank.com.

Passkeys are WebAuthn credentials that sync across devices via the OS keychain (iCloud Keychain, Google Password Manager, etc.). They provide phishing-resistant authentication without requiring a dedicated hardware token.

Passkeys are not yet universal, but every major OS and browser supports them as of 2024. They are the clearest path to eliminating password-based phishing entirely for consumer accounts.

Part 4: Session management and JWTs (30 min)

After authentication, the server needs a way to recognize the user on subsequent requests without requiring re-authentication on every call.

Traditional server-side sessions:

The server generates a random session ID and stores the session state (user ID, roles, expiry) in a server-side store (database, Redis, etc.). The session ID is sent to the client as a cookie. The client sends the cookie on every request; the server looks up the session state.

Revocation is simple: delete the session from the store. The session ID in the cookie becomes invalid immediately.

JWTs (JSON Web Tokens):

A JWT is a signed (and optionally encrypted) token containing claims: who the user is, their roles, the token's expiry, and anything else the issuer chooses to include. The server signs the token with its private key; the client stores it and presents it on every request; the server verifies the signature without a database lookup.

JWTs enable stateless sessions: the server doesn't need to look up session state in a store on every request. This is appealing for scalability (no session-store bottleneck) and for microservices (any service can verify the token if it has the public key).

The revocation problem: there is no standard way to revoke a JWT before it expires. If the server issued a JWT with a 24-hour expiry to an account that was just compromised and the user's password was changed, the JWT remains valid for up to 24 hours.

Common workarounds:

  • Short expiry (15 min) + refresh tokens: frequent revocability but frequent re-authentication burden.
  • Token blocklist (database of revoked JTIs): recovers revocability but reintroduces the database lookup that JWTs were supposed to avoid.
  • WebSockets with server-push invalidation: complex.

The takeaway for SEC-101: JWTs are credentials, not opaque identifiers. A user who possesses a valid JWT has all the access that JWT encodes, for its full lifetime. Treat them like passwords: transmit only over TLS, store appropriately on the client, set short lifetimes for sensitive operations.

The "alg=none" JWT attack:

The JWT header specifies the signing algorithm. Early JWT libraries accepted "alg: none" and skipped signature verification. An attacker who modified a JWT's payload and set "alg: none" in the header could authenticate as any user. This is a classic broken-authentication bug: the control (signature verification) existed but was not enforced when the client presented "alg: none."


Lab exercises (~1.5 hr)

Lab 5: Broken-auth lab walk on OWASP Juice Shop (graded)

See labs/lab-5-broken-auth.md for the full lab.

OWASP Juice Shop ships as a Docker container (or runs at a provided URL). The lab focuses on the broken-authentication challenge category: at least 4 challenges involving session cookies, password reset flows, and authentication bypass.


Independent practice (~5 hr)

  • Reading (1 hr): Read the OWASP Session Management Cheat Sheet. Note the secure cookie attributes: HttpOnly (JavaScript cannot read the cookie), Secure (cookie only sent over HTTPS), SameSite=Strict or Lax (protects against CSRF). These attributes are the practical implementation of the controls discussed in lecture.
  • picoCTF spine (3 hr): Work in Web Exploitation challenges. Good targets: beginner challenges involving cookies, session tokens, or basic authentication bypass. Document each attempt thoroughly.
  • Reflection (1 hr): Write the prompts below.

Reflection prompts

  1. The "alg=none" JWT attack exploited a JWT library that accepted the client's claimed algorithm without enforcing that the signature matched. Which Saltzer and Schroeder principle does this violate? Which STRIDE category does it map to?

  2. Passkeys (WebAuthn) are phishing-resistant by design: the credential is bound to the site's cryptographic origin, not the site's visual appearance. Explain in plain English why a fake bank website cannot steal a passkey-based authentication even if the user is completely deceived by the fake site's appearance.

  3. You are reviewing a web application that stores sessions as JWTs with a 7-day expiry and no revocation mechanism. A user reports that their account was compromised. You immediately reset their password. Why has this not secured the account? What additional steps are required?


Week 6 of 14. Next: OWASP Top 10 I (Injection, broken authentication, sensitive data exposure).