← Concepts

阅读中文版本

Cross-Site Request Forgery (CSRF)

CSRF tricks a victim's browser into sending an authenticated state-changing request to another site. Defenses use SameSite cookies, CSRF tokens, and origin checks.

security

Definition

Cross-Site Request Forgery is an attack where a malicious site causes the victim's browser to send a request to a target site that the browser will automatically authenticate, typically through cookies. Because the browser attaches the cookie regardless of the initiating origin, the target server may execute a state-changing action the user did not intend. CSRF applies to requests authenticated by ambient credentials such as cookies or HTTP authentication, not to requests that require an explicit Authorization header the attacker cannot read.

Context and scope

CSRF matters for cookie-authenticated forms and APIs that change state, such as transfers, profile updates, and password changes. Token-based APIs using Authorization headers are generally not vulnerable to classic CSRF because the attacker cannot set that header cross-origin. Modern defenses combine SameSite cookies with server-side CSRF tokens and origin validation.

Common misconceptions

  • CSRF requires the attacker to read the response — classic CSRF only needs the request to be sent; the attacker may never see the response
  • HTTPS prevents CSRF — TLS protects transit, not the browser's automatic credential attachment
  • JSON APIs are immune — a form-encoded or text/plain request can still reach an endpoint that accepts multiple content types

Anti-patterns

  • Using GET for state-changing operations
  • Relying only on a custom header check while allowing cookie-authenticated simple requests
  • Storing CSRF tokens in cookies without binding them to the session

Related concepts

Related examples

Authoritative source

https://owasp.org/www-community/attacks/csrf

The attack model

The victim is signed in to bank.example with a cookie. They visit evil.example, which submits a hidden form to bank.example/transfer. The browser attaches the bank cookie, and the bank cannot distinguish this request from a legitimate one unless it checks something the attacker cannot reproduce.

Defenses

import crypto from 'node:crypto';

app.use((req, res, next) => {
  if (!req.session) return next();
  if (!req.session.csrf) req.session.csrf = crypto.randomBytes(32).toString('base64url');
  res.locals.csrfToken = req.session.csrf;
  next();
});

app.post('/transfer', (req, res) => {
  if (req.body.csrf !== req.session.csrf) return res.status(403).send('invalid csrf token');
  // perform the transfer
});

Set session cookies with SameSite=Lax or Strict and Secure. For high-risk actions, require re-authentication. Validate the Origin or Referer header as defense in depth, but do not rely on it alone.

When it matters

Use CSRF defenses for every cookie-authenticated state-changing route, including logout if logout is a POST. Compared to CORS, CSRF protection prevents the request from being honored, while CORS only controls whether the attacker’s page can read the response. APIs using explicit bearer tokens are not vulnerable to classic CSRF, but they have their own token-storage risks.

Pitfalls

A token that is static per user, leaked in a URL, or not bound to the session provides little protection. State-changing GET requests bypass many token checks entirely. Test by submitting a cross-origin form in a browser, not only with curl, because curl does not enforce browser credential rules.