What is CSRF (Cross-Site Request Forgery)? How it works and how to prevent it
Cross-Site Request Forgery (CSRF) tricks a logged-in browser into sending unwanted requests to a trusted site. This guide explains how the attack works and the defenses that stop it.
On this page
- How CSRF works
- What an attacker can do with CSRF
- Defenses that prevent CSRF
- Anti-CSRF tokens (synchronizer token pattern)
- SameSite cookies
- Fetch Metadata headers
- Origin and Referer header verification
- Double-submit cookie pattern
- What does NOT stop CSRF
- The relationship between XSS and CSRF
- FAQ
- What is the difference between CSRF and XSS?
- Do modern browsers protect against CSRF by default?
- Can CSRF attacks be launched from emails?
- Is CSRF still relevant in 2026?
- Summary
- Sources
Cross-Site Request Forgery (CSRF, also called XSRF) is an attack that tricks a user's browser into performing an unwanted action on a site where the user is already logged in. Unlike Cross-Site Scripting (XSS), which injects malicious code into a page, CSRF exploits the browser's normal behavior: automatically attaching cookies to every request to a site. An attacker does not need to steal credentials — they just need to trigger the browser to send a crafted request that carries the victim's valid session cookie.
CSRF is a confused deputy attack. The browser acts as an unwitting agent, following the attacker's instructions with the victim's authenticated identity. The server cannot tell the difference between a legitimate request from the victim and a forged one from the attacker's page, because both arrive with the same cookies and look identical to the server.
This guide explains how CSRF attacks work, what an attacker can achieve, and the defenses that reliably prevent them.
How CSRF works
For a CSRF attack to succeed, three conditions must be met:
- The user is logged into a target site and holds a valid session cookie.
- The target site performs an action based only on the presence of that session cookie (no secondary verification).
- The attacker can trigger an HTTP request to the target site from the user's browser.
The classic attack vector is a crafted link or auto-submitting form on an attacker's page. When the victim visits or clicks, the browser automatically attaches the victim's session cookie and sends the request to the target site. The server processes it as a legitimate, authenticated action.
A concrete example: a banking site at https://example-bank.com has a transfer endpoint:
POST /transfer
Content-Type: application/x-www-form-urlencoded
account=987654321&amount=1000&csrf_token=abc123
An attacker crafts a page with a hidden form:
<form action="https://example-bank.com/transfer" method="POST">
<input type="hidden" name="account" value=" attacker-account" />
<input type="hidden" name="amount" value="10000" />
</form>
<script>document.forms[0].submit();</script>
When a logged-in user visits the attacker's page, the browser submits the form. It includes the user's session cookie automatically. The bank sees a valid authenticated request and processes the transfer. The user may not even notice — the attacker's page redirects somewhere or stays blank.
The attack also works via an image or script tag:
<img src="https://example-bank.com/transfer?account=attacker&amount=10000" />
Even a GET request triggered this way executes the action if the endpoint accepts GET. This is why GET must never perform state-changing operations.
What an attacker can do with CSRF
CSRF is limited to the actions the target site exposes and the victim's own privileges. If the victim is a regular user, CSRF might change their email, update their profile, or make a purchase. If the victim is an administrator, CSRF can modify site settings, add or remove users, or compromise the entire application.
Common CSRF targets include:
- Account settings — changing the victim's email address, password, or security questions to lock the victim out.
- Financial transactions — transferring funds, authorizing payments, or modifying billing information.
- Social actions — posting a message, sending a message, or changing privacy settings.
- Administrative operations — creating or deleting user accounts, changing permissions, modifying site configuration.
CSRF cannot read the response of the forged request (due to the Same-Origin Policy), but it does not need to. The action executes regardless of whether the attacker sees the result.
Defenses that prevent CSRF
Anti-CSRF tokens (synchronizer token pattern)
The most widely recommended defense. The server generates a cryptographically random, unpredictable token for each user session or each request, and requires it in every state-changing request.
POST /transfer HTTP/1.1
Cookie: session=abc123
account=987654321&amount=1000&csrf_token=OWY4NmQwODE4ODRjN2Q2NTlhMmZl
The server validates that the submitted token matches the one stored for the session. An attacker on a different origin cannot read or guess the token value, so forged requests are rejected.
Token requirements (per OWASP):
- Unique per user session or per request.
- Secret — never transmitted in a URL or log.
- Unpredictable — generated with a cryptographically secure pseudo-random number generator (CSPRNG).
SameSite cookies
The SameSite attribute tells the browser when to omit the cookie from cross-site requests. It is defined in RFC 6265bis and supported in all modern browsers.
| Value | Behavior |
|---|---|
Strict |
Cookie is sent only on same-site requests. Most secure, but breaks legitimate cross-site navigation (e.g., clicking a link from an email). |
Lax |
Cookie is sent on same-site requests and top-level cross-site navigations using safe methods (GET, HEAD, OPTIONS). Most requests from other sites (POST forms, images, iframes) do not send the cookie. Recommended for most applications. |
None |
Cookie is sent on all requests. Requires Secure (HTTPS). Disables CSRF protection from the cookie. Use only when the cookie is needed for legitimate cross-site requests (e.g., embedded widgets). |
Setting SameSite=Lax for session cookies stops most CSRF attacks without breaking normal browsing. The major browsers now default new cookies to Lax when the attribute is not specified.
Fetch Metadata headers
Modern browsers send additional request headers that describe the context of the request. The Sec-Fetch-Site header indicates the relationship between the requester's origin and the target:
same-origin— request comes from the same site.same-site— request comes from the same site (including subdomain variation).cross-site— request comes from a different site.none— direct navigation (typed in address bar).
Servers can inspect Sec-Fetch-Site and reject unsafe cross-site requests (POST, PUT, PATCH, DELETE) from cross-site origins. This requires no client-side changes and works across all modern browsers (98%+ global coverage since 2023).
Example server-side check (per OWASP):
Sec-Fetch-Site: cross-site + POST → reject (403)
Sec-Fetch-Site: same-origin + POST → allow
Sec-Fetch-Site: cross-site + GET → allow (safe method)
Origin and Referer header verification
The Origin and Referer HTTP headers indicate the source of a request. Servers can check that the origin matches an allowed list. However, these headers are not always present — browsers do not send Origin on all requests, and Referer can be stripped by privacy extensions, HTTPS-to-HTTP transitions, or browser settings. Relying solely on these headers is not recommended, but they serve as useful supplementary checks.
Double-submit cookie pattern
When server-side state storage is not available, the double-submit cookie pattern provides a stateless alternative. The server sets a random token in a cookie. The client reads this cookie value and also includes it as a custom request header or form parameter. The server verifies that both values match. Because an attacker cannot read or set cookies on the target domain from a cross-site page, they cannot forge a matching value.
The signed double-submit variant binds the token to the session using HMAC with a server-side secret, adding protection against cookie injection attacks. The naive variant (without signing) is discouraged per OWASP because subdomains under attacker control can inject matching cookies.
What does NOT stop CSRF
Several common beliefs about CSRF prevention are wrong:
- Using HTTPS alone does not stop CSRF. Encryption protects the transport but not the request — the browser still sends the cookie.
- Secret cookies (a cookie whose value is unknown to the attacker) do not help. All cookies, including secret ones, are sent automatically with every request.
- Only accepting POST requests is not sufficient. POST forms can be submitted from an attacker's page just as easily.
- Checking the Referer header alone is unreliable because it can be absent or stripped.
- URL rewriting (embedding the session ID in the URL) exposes the session ID in browser history, server logs, and the Referer header sent to other sites.
The relationship between XSS and CSRF
Cross-Site Scripting (XSS) and CSRF are separate vulnerabilities, but XSS can defeat all CSRF protections. If an attacker injects a script into the target site itself, that script runs in the trusted origin and can read page content, including anti-CSRF tokens. It can also make direct requests with the user's cookies — no need to forge a request at all. This is why XSS prevention (input validation, output encoding) and CSRF prevention must both be implemented; they protect against different threats and together form defense in depth.
FAQ
What is the difference between CSRF and XSS?
XSS injects malicious script into a trusted page, letting the attacker read and modify page content or execute code in the user's context. CSRF tricks the user's browser into sending a legitimate-looking request without the user's knowledge. XSS can be used to steal CSRF tokens and launch CSRF attacks, but the two are distinct vulnerabilities with different root causes and defenses.
Do modern browsers protect against CSRF by default?
Modern browsers have improved the situation with the SameSite cookie default (most browsers now default to Lax for new sessions), but this is not a complete solution. Legacy sites that explicitly set SameSite=None remain vulnerable, and Lax only blocks certain cross-site vectors. Server-side CSRF protection (tokens or Fetch Metadata checks) is still required for applications that handle sensitive actions.
Can CSRF attacks be launched from emails?
Yes. HTML email clients that render content can trigger GET requests via embedded images or linked resources. This is why GET endpoints should never perform state-changing actions. For POST requests, email clients that render HTML forms can be exploited similarly to malicious web pages.
Is CSRF still relevant in 2026?
Yes. CSRF remains in the OWASP Top 10 and affects applications that do not implement proper defenses. While SameSite cookie defaults have reduced the overall attack surface, many existing applications still lack CSRF protections, and SameSite=None is still required for legitimate cross-site use cases (embedded widgets, single sign-on flows) where CSRF tokens remain essential.
Summary
CSRF exploits the browser's automatic cookie behavior to make authenticated requests look legitimate to the server. It requires the user to be logged in, the site to rely solely on session cookies for authentication, and the attacker to be able to trigger a request from the victim's browser.
The primary defenses are anti-CSRF tokens (synchronizer token pattern), SameSite=Lax session cookies, and Fetch Metadata header checks (Sec-Fetch-Site). These are complementary — defense in depth means using more than one. XSS can bypass CSRF protections, so both classes of vulnerability must be addressed together.
Sources
- OWASP — Cross Site Request Forgery (CC BY-SA 4.0)
- OWASP — Cross-Site Request Forgery Prevention Cheat Sheet (CC BY-SA 4.0)
- Wikipedia — Cross-site request forgery (CC BY-SA 4.0)
Sources
- OWASP — Cross Site Request Forgery (owasp.org/www-community/attacks/csrf
- CC BY-SA 4.0)
- OWASP — Cross-Site Request Forgery Prevention Cheat Sheet (cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Request_Forgery_Prevention_Cheat_Sheet.html
- CC BY-SA 4.0)
- Wikipedia — Cross-site request forgery (en.wikipedia.org/wiki/Cross-site_request_forgery
- CC BY-SA 4.0)
Share this guide
Related guides
- What is XSS (Cross-Site Scripting)? How it works and how to prevent it
Cross-Site Scripting (XSS) lets an attacker run their own JavaScript in another user's browser. This guide explains how the three types work and the defenses that stop them.
- What is authentication? Passwords, biometrics, SSO, and modern methods explained
Authentication is the process of verifying who you are. Learn how passwords, multi-factor authentication, biometrics, SSO, OAuth, and password managers work — and which methods offer the best protection for your application.
- What is SQL injection? How it works and how to prevent it
SQL injection is one of the most common web vulnerabilities — this guide explains how it works, the main attack types, and the secure coding practices that prevent it.