Cross-Site Request Forgery (CSRF)

CSRF causes a victim's authenticated browser to send an unintended state-changing request to a trusted site. Defenses ensure that the request originated from an authorized context rather than merely relying on the browser's automatically attached credentials.

CSRF is possible when a server accepts a state-changing request based primarily on credentials that a browser supplies automatically, such as a session cookie. An attacker can place a request on a different origin, while the victim's browser may still attach the target site's credentials.

A typical defense is an unpredictable CSRF token tied to the user's session or request context. The legitimate application includes that token in a form field or custom request header, and the server verifies it before performing the state-changing operation.

Cookie attributes also reduce CSRF exposure. `SameSite=Lax` or `SameSite=Strict` can prevent cookies from being sent in many cross-site contexts, while `SameSite=None` permits cross-site cookie use when paired with `Secure`. Applications should choose cookie settings according to their actual cross-site requirements.

For APIs using cookies, validating the `Origin` header is another useful defense when supported by the deployment. A server can also use the `Referer` header as an additional signal, although it should account for legitimate privacy-related omission or reduction of referrer information.

CSRF is distinct from XSS. CSRF abuses the browser's ability to send authenticated requests from another origin; XSS executes attacker-controlled script in the application's origin. Strong output encoding and script protections help against XSS, while CSRF-specific request validation addresses forged state-changing requests.

Key points

Interview questions

What is CSRF, and why does it happen?

CSRF occurs when an attacker causes a user's browser to send a request to a site where the user is already authenticated. Browsers can automatically attach credentials such as cookies to requests for that site. If the server accepts the request without verifying that it was intentionally generated by the application, the unwanted action can succeed. The attack is therefore especially relevant to cookie-based authentication and state-changing endpoints.

How does a CSRF token protect an application?

The application gives the legitimate client an unpredictable token associated with its authenticated context. The client sends that token with a state-changing request, commonly in a form field or custom header. The server checks that the supplied value matches the expected token before accepting the operation. An attacker on another origin generally cannot obtain the token needed to construct a valid request.

Does CORS protect against CSRF?

No, CORS and CSRF address different browser behaviors. CORS primarily determines whether browser JavaScript can read a cross-origin response. A cross-origin request can sometimes still be sent even when the response is inaccessible to the initiating script. CSRF protection therefore requires controls such as tokens, appropriate `SameSite` cookies, or origin validation.

How does `SameSite` help mitigate CSRF?

`SameSite` determines whether a cookie is sent in a cross-site context. `Strict` applies the strongest restriction, while `Lax` permits some cross-site navigation cases; `None` allows cross-site cookie sending when the cookie also uses `Secure`. By reducing when authentication cookies accompany cross-site requests, these settings can substantially reduce CSRF exposure. They should still be selected according to the application's required navigation and embedding behavior.

What CSRF defenses would you use for a cookie-authenticated frontend application?

I would first establish the application's legitimate cross-site requirements and then combine defenses rather than relying on a single mechanism. For state-changing operations, I would use a robust CSRF-token strategy and configure session cookies with an appropriate `SameSite` policy. I would also consider validating `Origin` on sensitive endpoints and ensure state-changing actions are not exposed through unsafe GET semantics. Finally, I would account for XSS because script execution in the trusted origin can undermine many client-visible CSRF mechanisms.