Cross-Site Request Forgery (CSRF)

A web application vulnerability in which an attacker makes a logged-in user perform an action unknowingly, because the browser itself adds their session cookie to the request.

Cross-Site Request Forgery (CSRF) — also called XSRF or a session riding attack — is a web application vulnerability. It lets an attacker make a logged-in user perform an action without meaning to: change a password, send a transfer, grant someone privileges. The trick relies on the fact that the browser automatically adds the victim’s session cookie to every request. The server sees a valid session and carries out the command, because it trusts the logged-in user — it does not check whether the request really came from its own site.

When is a CSRF attack even possible?

According to PortSwigger’s classification, three conditions must all hold at once:

  • There is a meaningful action to perform. The application has an operation the attacker cares about — changing an email, changing a password, transferring funds, granting privileges.
  • The session relies only on a cookie. The application recognizes the user purely from a session cookie that the browser sends on its own. The request carries no extra, hard-to-guess secret.
  • Every request parameter is predictable. The attacker knows or can guess every value needed. The request contains nothing unpredictable, such as a CSRF token or the current password.

How does a CSRF attack work?

The server trusts the victim’s logged-in session — or rather, the victim’s browser. CSRF abuses that trust. A typical sequence looks like this:

  1. The victim is logged in to some application and holds a valid session cookie in the browser.
  2. The attacker prepares a page with a hidden request to that application — for example a form that submits itself via JavaScript, or an <img> tag pointing at a vulnerable address.
  3. The victim — still logged in — opens that page, arriving from a link in an email, a forum post, or an advert.
  4. The browser sends the request to the application and, as usual, adds the victim’s session cookie itself.
  5. The server sees a valid session and performs the operation as if the user had ordered it deliberately.

An important detail: the attacker cannot see the server’s response — the same-origin policy blocks that. CSRF is therefore used to trigger an action, not to peek at data. The attack works “blind,” which is what sets it apart from data theft.

CSRF via GET or POST?

How the request is delivered depends on the method the vulnerable address accepts:

  • GET — the easiest to exploit. An <img src="https://bank.example/transfer?to=attacker&amount=1000"> tag is enough. The browser tries to load the “image” and, in passing, sends the request together with the cookies. Operations that change data should never be reachable via GET.
  • POST — requires auto-submitting a hidden form, usually with JavaScript. POST on its own does not protect against CSRF — a common myth.

A separate variant is Login CSRF. Here the attacker forces the victim to log in to the attacker’s own account, so that whatever the victim enters there — history, a saved card — can be viewed later.

What can a successful CSRF attack lead to?

  • An email or password change, and with it a takeover of the account.
  • An unauthorized transfer or other transaction.
  • Changed privileges, a deleted account, altered security settings.
  • Control over the whole application when the victim is an administrator — a single request can change its configuration.

How does CSRF differ from XSS?

These are two different vulnerabilities that are easy to confuse:

  • XSS (Cross-Site Scripting) injects and runs attacker-controlled script on a trusted page. It gives the attacker control over how the page behaves and the ability to read data — including CSRF tokens.
  • CSRF runs no code and reads no response. It only forces a forged request to be sent within a session that already exists.

This difference matters for defense: XSS defeats every anti-CSRF safeguard. A script running on the victim’s side can read the token and send a valid request. That is why removing XSS is a precondition for any CSRF protection to make sense.

How do you prevent CSRF attacks?

The basic rule: tie every request that changes data to a secret the attacker’s page neither knows nor can attach. The methods below are described by OWASP in its CSRF Prevention Cheat Sheet.

CSRF token (Synchronizer Token Pattern)

The most common method for applications that keep session state on their own side. The server generates a unique, cryptographically strong token (for the whole session or for a single request), stores it locally, and places it in a hidden form field or a header. The token is not an ordinary cookie, and the server rejects requests without the correct value. The attacker’s page cannot read this token — again, the same-origin policy blocks it — so it cannot build a valid request.

Double Submit Cookie (for stateless applications)

  • Naive variant — the same random value goes both into a cookie and into a request parameter, and the server compares the two. The attacker cannot read someone else’s cookie, so cannot repeat it in the parameter.
  • Signed (HMAC) variant — recommended — the token is cryptographically bound to the session. This protects against a cookie planted from a subdomain or another, more weakly isolated place.

Custom request headers

Good for application programming interfaces (APIs) and AJAX/XHR requests sent in the background. The client adds its own header, such as X-CSRF-Token or X-Requested-With. Adding such a header across sites forces an extra checking request (a CORS preflight) that a simple attacker page cannot pass. No server-side token storage is needed.

SameSite cookies

The SameSite attribute decides whether a cookie is attached to requests that come from another site:

  • Strict — the cookie is never sent on any request from another site.
  • Lax — the default in modern browsers (in Chrome since 2021). The cookie is sent only when you simply navigate to the page using a safe method (GET).
  • None — the cookie is always sent, but this requires the Secure attribute.

SameSite is an extra layer (defense-in-depth), not a standalone solution. It will not protect against changes made via GET, nor against an attack from the same site, for example from a subdomain. It needs to be combined with a CSRF token.

Checking Origin / Referer headers and Fetch Metadata

The server can compare the Origin and Referer headers against its own address, or inspect Sec-Fetch-Site and reject the value cross-site for operations that change data. These headers are sometimes omitted, though — during redirects or with certain privacy settings — so they are treated as a supplementary control, not a primary one.

Why does CSRF matter for monitoring and detection?

CSRF is an application-layer attack, launched from the victim’s browser. The request itself looks like ordinary traffic from a logged-in user — there is no exploit signature and no visible anomaly at the packet level. From a security team’s (SOC) point of view, the useful signals are therefore indirect, based on links between events:

  • Operations that change data (an email or password change, a transfer) whose Referer/Origin header points to a foreign site, or that lack the expected token.
  • Unusual request sequences — a sensitive action without the earlier form fetch that normally delivers the token.
  • A sudden spike of traffic to specific data-changing addresses, coinciding with visits to external domains (data from proxies, WAF and application server logs, NetFlow/IPFIX telemetry).
  • Actions that are inconsistent in time or geography within a single session.

Application server logs, WAF logs, and network telemetry make it possible to catch mass or repeated CSRF attempts, work out the scope of an incident after the fact, and tell forged requests apart from ordinary activity. This complements the defenses built into the application itself.

Learn more