Cross-site request forgery (CSRF)
In web application security, cross-site request forgery (CSRF) is an attack that makes a logged-in user’s browser send a state-changing request to a site that trusts their session cookie. The user does not have to click anything on the target site: the request rides on credentials the browser attaches automatically.
How it works
A browser attaches cookies according to the destination of a request, not according to the page that triggered it. If an endpoint changes state and the only thing proving who is asking is a session cookie, any page on the internet can trigger that change: it renders a form aimed at the target, submits it with script, and the browser attaches the cookie on the way out. The attacker never reads the response and does not need to, because the damage is the write.
Two controls close it. An anti-CSRF token ties each request to a value the attacking page cannot read or guess, because the same-origin policy stops it reading the target’s HTML. The SameSite cookie attribute stops the cookie being attached to cross-site requests at all, which is why the cookie security attributes are the first thing to read.
What goes wrong
Major browsers now treat a cookie with no SameSite attribute as Lax, so the textbook attack against a form POST is no longer the common case. What we still find are the edges. Top-level navigation by GET still carries the cookie under Lax, so any endpoint that changes state on a GET stays exploitable. Some browsers keep a short grace window after a cookie is issued during which a cross-site POST still carries it. Endpoints that accept the simple content types, form encoding or plain text, can be reached by a cross-site form with no preflight, which catches APIs that assumed the browser would stop it. A token that is generated but never verified, or verified only when it happens to be present, is not a control. And cross-site scripting defeats every CSRF defence at once, because script running on the origin can read the token.
Where this shows up in an audit
We test it by taking a real authenticated request, stripping or altering the token, replaying it from a different origin, and then checking whether the state actually changed on the server rather than whether the response looked like an error. The evidence in the report is the record before and after, not a screenshot of a proxy. Severity follows the action: a forged request that changes an email address is an account takeover path, one that flips a display preference is an observation. This is part of how we test state-changing requests in a web application.