EXERCISE 2 — Why XSS defeats synchronizer-token CSRF defence ============================================================= THE SETUP: A synchronizer token (Chapter 5) defends against CSRF by requiring each state-changing request to include a secret, unpredictable token that the server issued and tied to the user's session. The defence WORKS because a cross-site attacker (on evil.com) CANNOT READ the token out of the target's page -- the Same-Origin Policy blocks cross-origin reads. So the attacker can't put the right token in a forged request. WHAT XSS CHANGES: - XSS means the attacker's JavaScript runs ON the target page, at the target's OWN origin (same-origin), inside the victim's authenticated session. - Same-origin script is NOT blocked by the Same-Origin Policy from reading the page it runs in. So the injected script can simply READ the token. WHAT THE INJECTED SCRIPT DOES TO THE TOKEN: 1. Read the token straight from where the app put it, e.g.: var t = document.querySelector('input[name=csrf_token]').value; (or from a meta tag, JS variable, or a non-HttpOnly cookie). 2. Build a request to the sensitive endpoint INCLUDING that valid token: fetch('/email/change', { method:'POST', headers:{'X-CSRF-Token': t}, // same-origin can set headers credentials:'same-origin', body: new URLSearchParams({email:'attacker@evil.com'}) }); 3. The request is same-origin, carries the cookie, AND carries a VALID token -> the server accepts it. The CSRF defence is bypassed entirely. - Same-origin script can also READ responses and set custom headers, so it is strictly more capable than any cross-site CSRF. THE SECURITY PRINCIPLE (defence ordering): - Synchronizer tokens REST ON THE ASSUMPTION that the attacker cannot read your page/token. XSS violates that assumption, so no token scheme can protect a site that has XSS. - Therefore XSS is strictly MORE SEVERE than CSRF, and must be fixed FIRST. You cannot "tokens-your-way-out" of an XSS hole. - Principle: a defence that assumes attacker code can't run in your origin is void once attacker code CAN run in your origin. Eliminate same-origin code injection (XSS) before relying on same-origin secrets (tokens). PRACTICAL COROLLARY: - Mark session/token cookies HttpOnly (so script can't read them), set a strong Content-Security-Policy, and encode all output -- i.e. close XSS -- as the FOUNDATION beneath your CSRF tokens, not as an afterthought.