100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Security

CSRF Explained and Prevention

Cross-Site Request Forgery tricks a logged-in user's browser into submitting an unwanted, state-changing request to a site it trusts, using the victim's own valid session.

Access Control & ConfigIntermediate9 min readJul 10, 2026
Analogies

What Is CSRF?

Cross-Site Request Forgery (CSRF) exploits the fact that browsers automatically attach cookies to any request sent to the cookie's origin domain, regardless of which site initiated that request. If a user is logged into bank.example.com and their browser holds a valid session cookie, a malicious page on evil.example can silently trigger a request to bank.example.com/transfer, and the browser will attach the legitimate session cookie exactly as if the user had submitted the form themselves. The server sees a validly authenticated request and has no built-in way to know the user did not intend to send it, which is what makes CSRF fundamentally a confused-deputy problem rather than an authentication bypass.

🏏

Cricket analogy: It's like a fan's signed entry pass being usable by anyone who finds it lying around, letting a stranger walk into the players' area on the fan's identity without the fan ever realizing their pass was used.

Anatomy of a CSRF Attack

A typical CSRF attack targets state-changing actions — changing an email address, transferring money, deleting an account — rather than data reads, since the attacker cannot see the response, only trigger the side effect. The classic vector is an auto-submitting HTML form hosted on an attacker-controlled page: the victim only needs to visit that page while logged into the target site, and JavaScript submits the form on page load with no click required. GET-based CSRF is even simpler, since a single <img src="..."> tag pointing at a state-changing URL will fire automatically. Attacks succeed whenever the target endpoint relies solely on cookie-based session identification without any secondary proof that the request originated from the site's own UI.

🏏

Cricket analogy: State-changing-only targeting is like a scam that only bothers forging a request to change a player's contract terms, not to view the public scorecard, since forging a read gains the attacker nothing they can't already see.

html
<!-- Hosted on evil.example  victim just has to load this page while logged in -->
<body onload="document.forms[0].submit()">
  <form action="https://bank.example.com/transfer" method="POST">
    <input type="hidden" name="to" value="attacker-account" />
    <input type="hidden" name="amount" value="5000" />
  </form>
</body>
<!-- The browser attaches bank.example.com's session cookie automatically -->

CSRF is not the same as XSS. XSS runs attacker script in the context of the vulnerable site itself; CSRF runs from a completely different origin and merely relies on the browser's automatic cookie attachment. A site can be XSS-free and still be fully vulnerable to CSRF.

Preventing CSRF

The standard defense is the synchronizer token pattern: the server embeds a unique, unpredictable CSRF token in each form or page, and every state-changing request must include that token in the request body or a custom header; since evil.example cannot read bank.example.com's page to extract the token, it cannot forge a valid request. The double-submit cookie pattern is a stateless variant, where the token is set as a cookie and also required in the request body or header, and the server just checks they match. SameSite cookies (Lax or Strict) provide strong browser-level defense by refusing to send the cookie on cross-site requests in the first place, and modern frameworks default new cookies to SameSite=Lax. Best practice layers both: SameSite cookies as a baseline, plus explicit CSRF tokens for state-changing requests as defense in depth.

🏏

Cricket analogy: A CSRF token is like a one-time authentication code printed only on the official scorecard handed to the actual scorer, so a forged scorecard from outside the ground can never present the matching code.

javascript
// Express example using a CSRF token middleware
app.get('/transfer-form', (req, res) => {
  res.render('transfer', { csrfToken: req.csrfToken() });
});

app.post('/transfer', csrfProtection, (req, res) => {
  // csrfProtection middleware rejects the request if req.body._csrf
  // does not match the token issued for this session
  processTransfer(req.body);
  res.redirect('/success');
});

// Cookie config that adds a browser-level layer of defense
res.cookie('session', sessionId, {
  httpOnly: true,
  secure: true,
  sameSite: 'Strict',
});

Framework defaults: Rails, Django, and Spring all ship built-in CSRF protection enabled by default for form submissions. Disabling it (common when building a pure JSON API) requires an explicit, deliberate decision — and that API should then rely on SameSite cookies plus custom header requirements instead, since browsers won't auto-attach cookies to cross-origin fetch requests that require custom headers.

  • CSRF abuses the browser's automatic cookie attachment to forge state-changing requests using a victim's valid session.
  • It targets state-changing actions (transfers, deletes, settings changes), not data reads.
  • GET-based CSRF can fire from a single auto-loading image tag; POST-based CSRF typically uses an auto-submitting form.
  • CSRF is distinct from XSS — it doesn't require injecting script into the vulnerable site at all.
  • Synchronizer tokens (server-issued, per-session, embedded in forms) are the classic defense.
  • SameSite=Lax/Strict cookies provide a strong browser-level baseline defense.
  • Best practice layers SameSite cookies with explicit CSRF tokens for defense in depth.

Practice what you learned

Was this page helpful?

Topics covered

#Security#WebSecurityOWASPStudyNotes#CyberSecurity#CSRFExplainedAndPrevention#CSRF#Explained#Prevention#Anatomy#StudyNotes#SkillVeris