Cross-Site Request Forgery (CSRF): Is It Still a Problem?
Cross-site request forgery tricks a logged-in user's browser into sending a request they did not intend. Browsers attach cookies automatically, so if your app relies only on cookies to authenticate a state-changing request, a malicious site can trigger it.
A classic example
The victim is logged into bank.example. They visit an attacker's page containing:
<form action="https://bank.example/transfer" method="POST">
<input name="to" value="attacker" />
<input name="amount" value="1000" />
</form>
<script>document.forms[0].submit()</script>
The browser sends the request with the victim's session cookie, and the transfer happens.
How SameSite cookies changed things
Modern browsers support the SameSite cookie attribute:
Strict: the cookie is never sent on cross-site requests.Lax: sent on top-level navigations using safe methods like GET, but not on cross-site POSTs.None: always sent, requiresSecure.
Several major browsers now treat cookies without a SameSite attribute as Lax by default. This blocks the classic form-POST attack in many cases, which is why CSRF reports have declined.
Where CSRF still happens
- Cookies set with
SameSite=None, often for embedded widgets or cross-domain SSO. - State-changing GET requests, such as
/account/delete?confirm=1, whichLaxallows on top-level navigation. - Same-site but cross-origin attacks: a vulnerable subdomain such as
blog.example.comcan send requests treated as same-site toapp.example.com. - Older browsers or clients that do not enforce SameSite.
- Login CSRF: forcing a victim to log into the attacker's account, so their activity is captured.
- JSON endpoints that accept
text/plainor form content types.
How to prevent CSRF
- Set
SameSite=LaxorStricton session cookies explicitly. - Never change state with GET. Use POST, PUT, PATCH or DELETE.
- Use anti-CSRF tokens for cookie-authenticated forms. Most frameworks provide this.
- Verify the
Originheader on state-changing requests and reject unexpected origins. - Require a custom header, such as
X-Requested-With, for API calls. Cross-site forms cannot set custom headers without a CORS preflight. - Re-authenticate for sensitive actions, such as changing email, password or payment details.
Token-based APIs
If your API authenticates with a bearer token in the Authorization header rather than cookies, classic CSRF does not apply, because the browser does not attach the header automatically. Be careful if you ever fall back to cookie authentication on the same endpoints.
Testing for CSRF
Testing checks each state-changing endpoint for token validation, origin checks and cookie attributes, then attempts cross-site requests. SecurityInfinity flags missing protections on sensitive actions and gives framework-specific fixes. Start free.
Frequently asked questions
Do SameSite cookies make CSRF tokens unnecessary?
They reduce risk significantly, but defence in depth is still recommended, especially for sensitive actions and for users on older browsers.
Is CSRF relevant for single-page apps?
Yes, if the SPA's API uses cookies for authentication. If it uses bearer tokens in headers, CSRF risk is much lower.
What is login CSRF?
An attack that logs the victim into an account controlled by the attacker, so anything the victim enters is visible to the attacker.