What is a CSRF vulnerability?

3 min read Updated 2026-02-05

Cross-Site Request Forgery. An attack that tricks authenticated users into performing unintended actions on a web application. Prevented using CSRF tokens and SameSite cookies.

Common in: Banking applications E-commerce checkouts Account settings pages Admin panels Any state-changing forms

Understanding CSRF

CSRF exploits the trust that a web application has in the user's browser. If a user is logged into a site, a malicious page can trigger requests to that site, and the browser will automatically include authentication cookies. The attack works because the server can't distinguish between legitimate and forged requests. While modern browsers' SameSite cookie default has reduced CSRF prevalence, it remains a risk for applications with misconfigured cookies.

Examples

  • A hidden form on a malicious site that transfers money when visited
  • An image tag with src pointing to a state-changing URL
  • Malicious links in emails that perform actions when clicked
  • Auto-submitting forms embedded in malicious pages

How to Prevent

  • Use anti-CSRF tokens (synchronizer token pattern) in all state-changing requests
  • Set SameSite=Strict or SameSite=Lax on session cookies
  • Verify Origin and Referer headers as additional defense
  • Require re-authentication for sensitive actions (password change, money transfer)
  • Use custom headers for AJAX requests (they require CORS preflight)
  • Consider double-submit cookie pattern for stateless applications
  • Log and monitor for CSRF-like patterns (same user, multiple origins)

Code Examples

CSRF Attack Example

When a logged-in user visits the attacker's page, the hidden form submits a transfer request to the bank. The browser includes the victim's session cookie, making it look legitimate.

<!-- Attacker's malicious page: evil.com/attack.html -->
<!-- Victim is logged into bank.com -->

<h1>You won a free iPhone!</h1>

<!-- Hidden form that auto-submits -->
<iframe style="display:none" name="csrf-frame"></iframe>
<form action="https://bank.com/transfer" method="POST" target="csrf-frame" id="csrf-form">
  <input type="hidden" name="to" value="attacker-account" />
  <input type="hidden" name="amount" value="10000" />
</form>

<script>
  // Form auto-submits when page loads
  document.getElementById('csrf-form').submit();
</script>

<!-- Victim's browser sends their session cookie automatically! -->

CSRF Token Protection

CSRF tokens are unique per session and must be included in forms. Attackers can't obtain the token from another domain due to same-origin policy.

Vulnerable
// VULNERABLE: No CSRF protection
app.post('/transfer', (req, res) => {
  const { to, amount } = req.body;
  // Transfers money - no verification this is a legitimate request
  transferMoney(req.user.id, to, amount);
});
Secure
// SECURE: CSRF token validation
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });

// Add token to forms
app.get('/transfer', csrfProtection, (req, res) => {
  res.render('transfer', { csrfToken: req.csrfToken() });
});

// Validate token on submission
app.post('/transfer', csrfProtection, (req, res) => {
  // csurf middleware validates the token automatically
  // Invalid/missing token = 403 error
  const { to, amount } = req.body;
  transferMoney(req.user.id, to, amount);
});

// In your form (EJS/Pug/etc):
// <input type="hidden" name="_csrf" value="<%= csrfToken %>">

SameSite Cookie Protection

Vulnerable
// VULNERABLE: Cookie sent with all requests
res.cookie('session', token, {
  httpOnly: true,
  secure: true
  // No SameSite = vulnerable to CSRF
});
Secure
// SECURE: SameSite prevents cross-origin cookie sending
res.cookie('session', token, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict'  // Or 'lax' for better UX
});

// 'strict': Cookie never sent cross-origin
// 'lax': Cookie sent for top-level navigations (links)
//        but not for forms, iframes, AJAX

// Modern browsers default to 'lax' but explicit is better

Real-World Incidents

Netflix

2006

CSRF vulnerability allowed attackers to change user account details, add DVDs to queues, and change shipping addresses by tricking users into visiting malicious pages.

Impact: Account hijacking potential for millions of subscribers

ING Direct

2008

CSRF vulnerability in the online banking portal allowed attackers to transfer funds from victim accounts.

Impact: Potential for direct financial theft from customers

YouTube

2008

CSRF allowed attackers to perform actions on behalf of logged-in users, including adding videos to favorites and subscribing to channels.

Impact: Manipulation of user accounts and video metrics

Worried about CSRF in your app?

Our security audits identify vulnerabilities like this before attackers do. Get expert manual review of your codebase.