Cross-Site Request Forgery (CSRF) Explained
Cross-site request forgery, often shortened to CSRF or XSRF, is an attack that tricks a victim's browser into sending an unwanted authenticated request to a site where the user is logged in. Because browsers automatically attach cookies to requests for a given site, a malicious page can cause state-changing actions, such as changing an email address or transferring funds, without the user's knowledge. CSRF abuses the trust a site places in the user's browser rather than any flaw in the user's credentials.
How CSRF Works
CSRF depends on a few conditions working together:
- The victim is authenticated to the target site, typically through a session cookie.
- The target performs a state-changing action based on a predictable request.
- The site authorizes that action using only the automatically sent cookie.
An attacker crafts a page that issues a request to the target. When the victim visits the attacker's page while logged in, the browser sends the request along with the victim's cookies. From the server's perspective, the request looks legitimate because it carries a valid session.
A classic example is an auto-submitting form that fires as soon as the page loads:
<form action="https://bank.example/transfer" method="POST">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="1000">
</form>
<script>document.forms[0].submit()</script>
The victim never intended to submit this form, but the browser attaches their session cookie and the transfer proceeds if no anti-CSRF control is present.
CSRF is not limited to forms. Any request the browser can be induced to make cross-site is a candidate, including image tags that trigger GET requests and script-driven POST submissions. This is why endpoints that change state must never rely on the HTTP method alone for protection, and why safe methods such as GET should never perform state changes in the first place.
Defenses Against CSRF
Effective protection ensures a request genuinely originated from the application's own pages, not from an attacker-controlled context.
Anti-CSRF Tokens
The synchronizer token pattern is the traditional defense. The server generates a random, per-session or per-request token, embeds it in forms, and rejects any state-changing request lacking the correct value. Because the attacker's page cannot read the token from another origin, it cannot forge a valid request.
<form method="POST" action="/account/email">
<input type="hidden" name="csrf_token" value="4f3c9a...">
<input type="email" name="email">
</form>
SameSite Cookies
The SameSite cookie attribute instructs the browser not to send a cookie on cross-site requests, which blocks the core mechanism CSRF relies on. SameSite=Lax sends cookies only on top-level navigations, while SameSite=Strict withholds them from all cross-site requests. This is covered in depth in secure cookies and provides strong, low-effort protection, though tokens remain valuable as defense in depth.
Double-Submit Cookie
When storing per-session state is undesirable, the double-submit pattern sends the token both as a cookie and as a request parameter or header. The server confirms the two match. Because a cross-site attacker cannot read the cookie or set a custom header on the victim's request, this pattern resists forgery when implemented carefully.
Custom Headers and CORS
APIs consumed by JavaScript can require a custom header, such as X-Requested-With. Browsers only allow such headers on same-origin requests or after a successful preflight, and a properly configured CORS policy will not grant cross-origin permission. Attackers therefore cannot attach the required header from another site.
Verify Origin and Referer
As an additional check, servers can validate the Origin or Referer header on state-changing requests and reject those from unexpected origins. This complements tokens but should not be the sole defense, because these headers can be absent in some scenarios.
Re-Authenticate for Sensitive Actions
For the highest-value operations, such as changing a password, updating a recovery email, or moving money, require the user to re-enter their password or complete a step-up challenge. Because an attacker driving a forged request cannot supply that fresh proof, re-authentication stops the action even if another control is missing or misconfigured.
What CSRF Is Not
It is important to distinguish CSRF from other attacks. CSRF causes the browser to send a request but does not let the attacker read the response, since the same-origin policy blocks that. If an attacker can run script on the site itself, that is cross-site scripting, a more severe issue that can defeat CSRF tokens outright. Protecting against both requires separate controls.
Prevention Checklist
- Require an unpredictable anti-CSRF token on every state-changing request.
- Set
SameSiteon session cookies, defaulting toLaxor stricter where the flow allows. - Use HTTP methods correctly, ensuring GET requests never change state.
- Validate
Originfor sensitive endpoints as an extra layer. - Re-authenticate or require confirmation for high-value actions such as password or email changes.
Key Takeaways
- CSRF forces an authenticated browser to send unintended state-changing requests using automatically attached cookies.
- The attack works only when a site authorizes actions based solely on cookies with no unpredictable token.
- Synchronizer tokens and the
SameSitecookie attribute are the primary, complementary defenses. - Custom headers with correct CORS and Origin checks add further protection for APIs.
- Ensure GET never changes state and require confirmation for sensitive actions.