EXERCISE 3 — Synchronizer vs double-submit: when to use which ============================================================== COMPARISON: Axis | Synchronizer token | Double-submit cookie ----------------|---------------------------|--------------------------- Server storage | REQUIRED (token per | NONE -- stateless; server | session, stored server- | just compares the cookie | side) | copy vs the header copy Statelessness | stateful (needs session | stateless-friendly (no | store / sticky state) | per-user server state) Main weakness | storage cost; per-request | cookie injection from a | rotation breaks back- | subdomain / sibling XSS / | button & multiple tabs | non-HTTPS (naive variant); | | fix with signed/HMAC + __Host- RECOMMENDATIONS: (a) Server-rendered Rails app: -> SYNCHRONIZER TOKEN. Rails already keeps server-side session state and renders forms server-side, so storing a per-session token is natural and free of the double-submit cookie pitfalls. (Rails' built-in protect_from_forgery / form_authenticity_token IS a synchronizer-style token.) Embed it in forms; validate on every non-GET request. (b) Stateless JSON API behind an SPA: -> DOUBLE-SUBMIT COOKIE (signed/HMAC variant). A stateless API doesn't want per-session server storage; double-submit fits because the SPA's HTTP client can read the token cookie and echo it in a header automatically (the Angular XSRF-TOKEN / X-XSRF-TOKEN flow). Use the SIGNED variant + __Host- prefix to avoid the cookie-injection weakness. (If the API uses bearer tokens in a header instead of cookies, CSRF may not apply at all -- Chapter 9.) WHY THE CSRF TOKEN COOKIE IS INTENTIONALLY NOT HttpOnly: - In double-submit, the CLIENT-SIDE JavaScript must READ the token cookie to copy its value into the request header. HttpOnly hides a cookie from JavaScript -- which would make that impossible. So the CSRF token cookie is deliberately readable (not HttpOnly). - This is a different cookie from the SESSION cookie, which SHOULD remain HttpOnly (no script ever needs to read it; hiding it limits XSS damage). Don't make the session cookie readable just because the CSRF cookie is. WHEN THAT BECOMES DANGEROUS: - Only if the site has XSS. Same-origin injected script could read the non-HttpOnly CSRF cookie and forge a valid header. But note: XSS defeats EVERY CSRF defence anyway (Chapter 4 -- it can read synchronizer tokens from the page too), so the non-HttpOnly CSRF cookie isn't a NET new weakness -- XSS is already game over. The real lesson: eliminate XSS; keep the session cookie HttpOnly; accept that the CSRF token cookie must be JS-readable for the pattern to function.