Question presented to candidate: "A user is logged into your site with a session cookie. They visit an unrelated, malicious page in another tab. Can that page make your API do something on their behalf?"
What a strong answer should cover:
- π CSRF (Cross-Site Request Forgery) exploits one specific browser behaviour: a browser automatically attaches cookies to a request to a site, regardless of which page or origin triggered that request. The attacker's page never reads the victim's cookie β it just gets the browser to send a request that carries it.
- CSRF is a different problem from CORS. CORS controls whether a script running on one origin can read the response of a cross-origin request. CSRF does not care about reading a response at all β a state-changing side effect (a transfer, a password change) happens whether or not the attacker's page can see what came back.
- The modern, primary defense is the
SameSitecookie attribute βStrict,Lax, orNoneβ which tells the browser itself when to withhold a cookie on a cross-site request, rather than relying on server-side logic to catch a forged request after the fact. - The precise, easy-to-get-wrong nuance:
SameSite=Lax(the modern browser default when unset) still allows a cookie through on a cross-site top-level GET navigation β e.g. a link the victim clicks. It blocks cross-sitefetch/XHR/iframe requests, but a plain link click is treated differently. This is exactly why a state-changing action must never be reachable via a GET endpoint. SameSite=Nonecookies are sent on every request regardless of origin, and modern browsers additionally require theSecureattribute alongsideNoneor the cookie is rejected outright.- A CSRF token (double-submit cookie, or a token embedded in the page and echoed back in a custom header) remains a valid defense-in-depth layer, especially for cookies that must be
SameSite=None(e.g. a cookie legitimately used cross-site, such as in an embedded widget) β the token is something the attacker's page cannot read cross-origin even though the cookie itself is sent. - The
csurfnpm package β long the default answer here β was deprecated and archived in 2022; a current answer should not name it as the recommended library.
Clarifying questions expected:
- "Is the vulnerable endpoint reachable via GET, or only via POST/PUT/DELETE?" β a GET endpoint with side effects defeats the Lax-blocks-cross-site-writes assumption entirely.
- "Does any cookie in this app need to be SameSite=None for a legitimate cross-site use case?" β that is exactly where a token-based layer earns its place on top of SameSite.
Code / implementation expected: Optional, but showing the double-submit-cookie check and, ideally, the SameSite behaviour itself is the most convincing thing to demonstrate.