The Lock Everyone Uses and Thousands Try to Pick
"Authentication is the one part of your application that, if wrong, compromises everything else."
CSE 135 — Full Overview | Review Questions
Proving identity — three factors, high stakes, deceptively hard.
| # | Factor | What It Is | Examples |
|---|---|---|---|
| 1 | Something you know | A secret only you should possess | Password, PIN, security question |
| 2 | Something you have | A physical object in your possession | Phone, hardware key, smart card |
| 3 | Something you are | A biometric characteristic | Fingerprint, face scan, retina |
The eternal "buy vs. build" question — applied to the most security-critical part of your app.
Services like Auth0, Firebase Auth, Supabase Auth, and Clerk handle password storage, hashing, MFA, compliance, and reset flows.
Most real-world apps land in between: delegate the hard parts (password hashing, MFA tokens, social login) while owning session management, authorization, and user data storage.
Never store passwords. Store proof that someone knows the password.
| Concept | Direction | Purpose |
|---|---|---|
| Encryption | Reversible — if you have the key, get the original back | Protecting data in transit or at rest |
| Hashing | One-way — cannot get the original from the hash | Storing proof of passwords |
password123 with plain SHA-256, it's already in a rainbow table. Fast hashing without salts is barely better than plaintext.
| Algorithm | Key Property | Status |
|---|---|---|
| bcrypt | Built-in salt, configurable work factor, intentionally slow | Battle-tested, widely supported, still good |
| scrypt | Memory-hard — requires significant RAM, not just CPU | Good alternative, used in some crypto systems |
| Argon2id | Memory-hard, resistant to GPU & side-channel attacks | Current recommendation (PHC winner) |
Every item on this list has been found in production systems — some with millions of users.
Login failed for user admin with password hunter2 — PII/secrets in logs is a general problem.
NIST 800-63B overturned decades of conventional wisdom — many organizations still haven't caught up.
angry purple unicorn battery powered by 7 beats P@ssw0rd!Password1!, Password2!, Password3!1! at the end| Policy | NIST Recommendation | Common (Bad) Practice |
|---|---|---|
| Minimum length | 8 absolute min, 12+ recommended | 6 characters (far too short) |
| Maximum length | At least 64 characters | 16-character cap (you're hashing it anyway) |
| Complexity rules | Don't require them | Must have upper, lower, number, symbol |
| Expiration | Don't expire unless compromised | Every 90 days |
| Breach check | Yes, at registration | Not done at all |
A correct password hash is necessary but not sufficient.
| Technique | How It Works | Trade-off |
|---|---|---|
| Rate limiting | Cap attempts per account/IP in time window | Hard cutoff = DoS vector (attacker locks any account) |
| Tarpitting | Progressive delays: 1s after 3 fails, 5s after 5, 30s after 10 | More elegant — expensive for attacker, mild for real users |
| Temp lockout | 15 min after N failures | Reasonable balance |
| Permanent lockout | Locked until admin intervention | DoS vulnerability — attacker can lock every account |
| CAPTCHA | Challenge after many failures | Last resort — accessibility problems, increasingly solvable by AI |
Reset, never recover. If a service can send you your password, it stored it wrong.
Contextual signals beyond username and password — same tech as ad-tech tracking.
Authentication happens once. HTTP is stateless. How do you remember they're logged in?
| Aspect | Server-Side Sessions | JWT (JSON Web Tokens) |
|---|---|---|
| Storage | Server (memory, Redis, DB) | Client (cookie or header) |
| Revocation | Easy — delete on server | Hard — can't revoke before expiry without blacklist |
| Scaling | Needs shared store (Redis) | Stateless — any server can verify |
| Size | Small session ID in cookie | Larger token with embedded claims |
| Best for | Traditional web apps | APIs, microservices, SPAs |
| Flag | Purpose | Omitting It |
|---|---|---|
HttpOnly | Cookie cannot be accessed by JavaScript | XSS attacks can steal the cookie |
Secure | Cookie only sent over HTTPS | Cookie transmitted in plaintext over HTTP |
SameSite=Strict / Lax | Cookie not sent on cross-origin requests | Vulnerable to CSRF attacks |
Node.js assembles libraries; PHP bundles auth primitives into the language.
bcrypt / bcryptjs for password hashingexpress-session + connect-redis for sessionsjsonwebtoken for JWT-based authpassport for strategy-based auth (local, OAuth, SAML)password_hash() and password_verify() are built-in — no packages to install, no version conflicts, no supply-chain risk. Node requires npm install bcrypt with native C++ bindings. Both produce correct bcrypt hashes — PHP is simpler to get right.
Let Google handle passwords — compelling idea, but is it?
OAuth 2.0 is authorization ("can this app access my photos?"). OIDC adds an identity layer on top — ID tokens with user claims (name, email, picture).
Log in once → authenticated across all trusting services. Enterprise SSO (SAML/OIDC) = one login for email, Slack, GitHub, internal tools.
Benefits are real — costs are rarely discussed honestly.
"Sign in with Google" gives Google a log of every time your user visits your site. For an advertising company, this is valuable behavioral data you're handing over for free.
Start with openid email, but providers make it easy to request more: contacts, calendar, drive files. Consent screens become checkboxes users click through without reading.
Social login costs nothing in dollars. But the currency is your users' privacy. The provider knows which services each person uses, when, and how often.
You trust the provider with your users' identity. The provider has no obligation to your users — they're not the customer, they're the product.
Keycloak, Ory, Authentik — OAuth/OIDC capabilities without sending user data to a third party. Protocol benefits without the surveillance trade-off. Cost = infrastructure and maintenance.
Even if the password is stolen, the attacker still needs the second factor.
| Method | How It Works | Strength | Weakness |
|---|---|---|---|
| Hardware keys (FIDO2/WebAuthn) | USB/NFC, cryptographic challenge-response | Phishing-resistant, no shared secrets | Cost (~$25-50), can be lost |
| TOTP apps | Shared secret + time = 6-digit code; offline | No network needed, widely supported | Phishable (fake site trick) |
| Push notifications | "Was this you?" tap to approve | Convenient, low friction | MFA fatigue attacks |
| SMS codes | 6-digit code via text | Familiar, no app needed | SIM swapping, SS7 intercept |
| Email codes | Code or link sent to email | Universal (everyone has email) | Email accounts are targets |
| Backup codes | Single-use recovery codes | Work when all else fails | Must be stored securely |
Security measures designed to protect you create new vectors for surveillance.
Same phone number for 2FA on ten services = an adversary with carrier access can correlate all ten identities. Banking, social media, work VPN — all linked by one number.
Mandatory 2FA (especially SMS-based) requires giving an organization a phone number — a personal identifier with far more tracking potential than an email address.
The question is never "is this more secure?" but "is the security improvement worth the usability cost?"
Users have finite tolerance for security friction. Once the budget is spent, they find workarounds: reuse passwords, share accounts, write credentials on sticky notes, or stop using the service.
P@ssw0rd! not genuinely strong passwordsThe most secure option — a unique, random 30+ character password for every site — requires a tool most users don't have, don't understand, or don't trust. The most secure path isn't the easiest path.
15 concepts of authentication and identity in one table.
| Concept | Key Takeaway |
|---|---|
| The Auth Problem | Three factors (know, have, are); deceptively hard; security is mindset over technology |
| Build or Delegate? | Hosted services reduce risk but add dependency; most teams delegate the hard parts |
| Password Storage | Never store passwords; use bcrypt or Argon2id with unique salts and configurable work factor |
| Hall of Shame | Plaintext, reversible encryption, fast hashes, single salts, logged/emailed passwords |
| Password Policies | NIST 800-63B: length over complexity, no forced expiration, check breach databases |
| Hardening Login | Rate limiting, tarpitting, generic errors, constant-time comparison |
| Account Recovery | Reset, never recover; crypto-random, single-use, time-limited tokens |
| GeoIP & Risk Auth | Device + location + time + behavior = risk score; same tech as ad-tech tracking |
| Sessions & Tokens | Server sessions (revocable) vs. JWTs (stateless); always use HttpOnly, Secure, SameSite |
| Implementation | PHP: built-in password_hash/verify; Node: bcrypt package; both correct, PHP simpler |
| OAuth & Federated | Authorization Code flow; no password to store, built-in MFA; genuine benefits |
| The Trust Problem | Provider logs every login; vendor lock-in, scope creep; Keycloak/Ory as alternatives |
| MFA | Hardware keys > TOTP > push > SMS > nothing; MFA fatigue and SIM swapping are real |
| 2FA Surveillance | Phone-based 2FA = tracking vectors; hardware keys are the privacy-preserving answer |
| Security vs. Usability | Friction budgets are finite; passkeys make the secure path the easy path |