EXERCISE 2 — Why "we use JWTs so we're CSRF-safe" is wrong ========================================================== THE CLAIM: "Our auth uses JWTs (a stateless token), therefore we're not vulnerable to CSRF." WHY IT'S WRONG: - A JWT is just a TOKEN FORMAT (a signed JSON blob). It says NOTHING about how the browser sends it. CSRF depends entirely on whether the credential is AUTO-SENT by the browser -- which is determined by WHERE the JWT is STORED, not by it being a JWT. - If the JWT is stored in a COOKIE, the browser auto-attaches it on every request to the domain -- including forged cross-site requests. That is full classic CSRF exposure, identical to a session cookie. The "JWT" label changes nothing. JWT-IN-HEADER vs JWT-IN-COOKIE: Stored in Authorization header (kept in JS memory): CSRF exposure: NONE (classic). The browser won't auto-send it; the attacker can't read it to add it. Forged requests lack the token. XSS exposure: HIGH. Any same-origin script (XSS) can read the token from JS memory/storage and exfiltrate or misuse it. Stored in a cookie (often HttpOnly): CSRF exposure: FULL. Auto-sent cross-site -> must add SameSite + anti-CSRF tokens, just like a session cookie. XSS exposure: LOWER for the token itself -- HttpOnly means script CAN'T read the cookie value (though XSS can still RIDE the session by making same-origin requests). THE TRADE-OFF A TEAM IS ACTUALLY MAKING (cookie storage for HttpOnly): - By putting the JWT in an HttpOnly cookie, they REDUCE XSS token-theft risk (script can't read the token) but TAKE ON CSRF risk (auto-sent), which they must now mitigate with SameSite + CSRF tokens. - By putting the JWT in a header (JS memory), they AVOID classic CSRF but EXPOSE the token to XSS theft. - Neither is free: it's CSRF-exposure vs XSS-exposure. The right choice depends on your threat model, but you must consciously DEFEND THE SIDE YOU DIDN'T eliminate: cookie storage -> add SameSite + CSRF tokens header storage -> invest hard in XSS prevention + short token TTLs - There is no configuration where "we use JWT" by itself removes the need to think about CSRF. ONE-LINE TAKEAWAY: CSRF risk tracks STORAGE LOCATION (auto-sent cookie vs explicit header), not token FORMAT. A JWT in a cookie is just as CSRF-vulnerable as a session id.