EXERCISE 2 — The subdomain / cookie-injection attack on naive double-submit =========================================================================== THE ASSUMPTION NAIVE DOUBLE-SUBMIT MAKES: "The attacker cannot know or control the csrf cookie value, so they can't produce a matching header." Security rests entirely on the cookie's integrity + secrecy. WHY THAT ASSUMPTION IS WEAK -- THE COOKIE MODEL != SAME-ORIGIN POLICY: - Cookies are scoped by DOMAIN, and a subdomain can set a cookie on the PARENT domain. A cookie set with Domain=.example.com is shared across www.example.com, app.example.com, evil.example.com, etc. - So a host the attacker controls or has compromised -- evil.example.com, a sibling subdomain with an XSS, or (over plain HTTP) a network attacker -- can WRITE the csrf cookie for .example.com in the victim's browser. THE ATTACK, STEP BY STEP: 1. The attacker controls evil.example.com (a subdomain of the target's parent domain), or finds XSS on any *.example.com host. 2. From there they set a cookie: csrf=KNOWNVALUE; Domain=.example.com -> this overwrites/plants the CSRF cookie the victim's browser holds for the whole example.com family with a value the ATTACKER chose. 3. The attacker now hosts a forged request to app.example.com that includes a header X-CSRF-Token: KNOWNVALUE (they know it -- they planted it). (If they can run script on a subdomain, they can issue the request with that header same-site; or they craft the request so cookie and header both equal KNOWNVALUE.) 4. The server compares cookie (KNOWNVALUE) == header (KNOWNVALUE) -> MATCH -> the forged request is accepted. Naive double-submit is defeated. The root flaw: the server TRUSTED the cookie value as if only it could have set it, but the cookie was attacker-controllable. HOW THE SIGNED / HMAC VARIANT PREVENTS IT: - Instead of a bare random value, the token is bound to the user's SESSION with a server secret: token = value + "." + HMAC(serverSecret, sessionId + "!" + value) - On validation, the server RECOMPUTES the HMAC using the sessionId IT trusts (from the authenticated session) and its secret, and checks the token carries a valid signature for THIS session. - An attacker who merely SETS a cookie can choose `value`, but cannot produce a valid HMAC -- they don't know serverSecret and can't bind it to the victim's session. A planted cookie value the server didn't issue fails the signature check -> rejected. - So integrity no longer depends on the cookie being unwritable; it depends on a secret the attacker doesn't have. Cookie injection no longer helps. PRACTICAL NOTES: - Also set the cookie with the __Host- prefix (e.g. __Host-csrf) where possible: it forbids a Domain attribute, preventing subdomain scoping, and requires Secure + path=/. This blocks the parent-domain injection vector directly. - Use HTTPS everywhere (stops network injection) and fix subdomain XSS. - Use a maintained library (csrf-csrf) that implements the signed variant -- don't ship the naive cookie==header check.