stackademic

The leading education platform for anyone with an interest in software development.

Cross-Site Request Forgery (CSRF)

How attackers trick browsers into unwanted actions and how to block it

Overview

Cross-Site Request Forgery (CSRF) tricks a logged-in user's browser into sending an unwanted request to your site, such as changing their email or transferring money. It works because browsers automatically attach cookies to requests, even those triggered from a malicious page. The fix is to require proof that the request came from your own app, using tokens and cookie flags.

Syntax / Usage

Issue an unpredictable CSRF token, embed it in forms, and verify it on state-changing requests. Because attackers cannot read your token, they cannot forge valid requests.

// Server: generate and verify a per-session token
app.get("/form", (req, res) => {
  const token = createCsrfToken(req.session);
  res.render("form", { csrfToken: token });
});

app.post("/transfer", (req, res) => {
  if (!verifyCsrfToken(req.session, req.body._csrf)) {
    return res.status(403).send("Invalid CSRF token");
  }
  // Safe to perform the action
});

Examples

Include the token as a hidden field in every state-changing form:

POST /transfer HTTP/1.1
Content-Type: application/x-www-form-urlencoded

amount=100&to=alice&_csrf=8f3b2c9e1a...

Set SameSite on session cookies so they are not sent on cross-site requests:

res.cookie("session", token, { httpOnly: true, secure: true, sameSite: "strict" });

Common Mistakes

  • Assuming a login check alone protects state-changing endpoints
  • Performing writes on GET requests, which are easy to trigger remotely
  • Omitting SameSite cookie attributes
  • Reusing or exposing CSRF tokens so attackers can predict them
  • Forgetting CSRF protection on APIs that rely on cookie-based sessions

See Also

web-security-authentication web-security-xss web-security-cors