A reviewer flags that your web app relies only on the SameSite cookie attribute to stop CSRF. Why isn't that enough on its own, and how would you actually protect a state-changing endpoint?
technical-conceptual · Mid level · software-engineering
What the interviewer is really asking
Assesses whether the candidate understands that SameSite is defense-in-depth rather than a complete CSRF control, and can name a real anti-CSRF mechanism appropriate to the architecture (synchronizer token for stateful apps, double-submit cookie or custom header for stateless/API).
What to say
- Explain why SameSite alone is incomplete: SameSite=Lax/Strict reduces cross-site cookie sending, but it doesn't cover mutating GET requests, can be undermined by a vulnerability on a sibling subdomain, and browser support and default behavior vary, so OWASP treats it as defense-in-depth that co-exists with a token, not a replacement.
- Pick the right primary control for the architecture: a stateful server-rendered app uses the synchronizer token pattern (a per-session/per-request token the server issues and validates); a stateless or token-based API uses the double-submit cookie pattern or, for fetch/XHR APIs, a required custom request header that cross-site forms can't set.
- Mention modern reinforcements: validate the Origin/Referer header on state-changing requests, and where supported use Fetch Metadata (Sec-Fetch-Site) to reject cross-site requests, layered on top of SameSite cookies.
What to avoid
- Claiming SameSite=Strict fully solves CSRF so no token is needed.
- Confusing CSRF with XSS or reaching for CORS as the fix — CORS governs cross-origin reads, not forged state-changing writes.
- Proposing to defend by checking only the User-Agent or by putting the endpoint behind a CAPTCHA, neither of which addresses the forged-request mechanism.
Example answers
Strong: SameSite is good defense-in-depth but not complete: it doesn't help with mutating GET requests and a compromised sibling subdomain can still send cookies, and OWASP says to pair it with a token, not replace one. So for a stateful app I'd add a synchronizer token validated server-side on every POST, and for our JSON API I'd require a custom X-CSRF header plus an Origin check, keeping SameSite=Lax as a second layer.
Weak: We set the cookie to SameSite=Strict, so cross-site requests can't carry the session and CSRF is basically handled — adding tokens on top would just be extra complexity for no real gain.