Articles

What Is CSRF? Cross-Site Request Forgery Explained

CSRF tricks a logged-in user's browser into sending an unwanted authenticated request. Cookies, tokens, and SameSite settings are the defense.

Chisato Chisato · · 4 min read
Red padlock icon overlaid on a keyboard

Cross-site request forgery (CSRF) is an attack that tricks a victim’s browser into sending an authenticated request to a site the victim is already logged into, without the victim intending it. The attacker doesn’t steal the victim’s session cookie — they don’t need to. They just get the browser to make a request that carries the cookie automatically, because that’s how cookies work by default.

How the attack actually works

Say a banking site has a poorly protected endpoint: POST /transfer moves money based on an authenticated session cookie, with no other check on who initiated the request. A user logs into that bank, then — without logging out — visits a malicious page in another tab. That page contains a hidden form or auto-submitting request targeting bank.com/transfer, with the attacker’s account as the destination.

Because the browser automatically attaches cookies for bank.com to any request sent to bank.com, regardless of which page triggered the request, the transfer request arrives at the bank’s server looking exactly like a legitimate request from the logged-in user. The server has no way to tell the difference unless it explicitly checks for one.

This is the essential shape of CSRF: it abuses the browser’s automatic, origin-agnostic handling of cookies, not any flaw in the cookie itself.

Why this is different from XSS

CSRF and cross-site scripting are frequently conflated because both are “cross-site” browser attacks, but they work in opposite directions. XSS gets malicious code to run on the victim’s own origin, which means it can read anything on that page, including tokens and cookies the JavaScript has access to. CSRF never runs any code on the target origin at all — it just forges a request from a different origin and relies on the browser sending credentials along automatically. A site can be fully immune to XSS and still be vulnerable to CSRF, and vice versa; they need separate defenses.

Defenses that actually work

CSRF tokens. The server embeds a unique, unpredictable token in each form or page, tied to the user’s session. Every state-changing request must include that token, and the server rejects requests without a valid one. An attacker’s forged request, coming from a different page, has no way to know the token, so it fails validation.

SameSite cookies. Modern browsers support a SameSite attribute on cookies. Setting it to Strict or Lax tells the browser not to send that cookie on requests originating from another site, which blocks the exact mechanism CSRF depends on. Lax is the default in most current browsers, which is a major reason CSRF is less common than it used to be — but it’s not a complete substitute for tokens, since some legitimate cross-site navigations still send Lax cookies.

Checking the Origin/Referer header. The server can compare the request’s Origin header against its own domain and reject mismatches. This is a reasonable defense-in-depth layer but shouldn’t be the only one, since these headers can be absent in some legitimate configurations.

Requiring custom headers on state-changing requests. Browsers block cross-origin scripts from setting arbitrary custom headers unless the target explicitly allows it via CORS. Requiring a custom header like X-Requested-With on state-changing API calls means a simple cross-site form post — which can’t set custom headers — can’t trigger the action.

Where JWTs fit in

Session-cookie-based apps are the classic CSRF target because the browser attaches the cookie automatically. APIs that use a JWT sent explicitly in an Authorization header rather than stored as a cookie are naturally resistant to CSRF, since the browser has no mechanism to attach an arbitrary header to a forged cross-site request the way it does with cookies. This is one reason token-based auth patterns common in single-page apps sidestep CSRF almost entirely — though if that same JWT is instead stored in a cookie for convenience, the CSRF risk comes right back and needs the same defenses as a session cookie.

CSRF vs the attacks it’s often confused with

CSRFXSSClickjacking
Where code runsNowhere (no injection needed)Victim’s own originNowhere (UI deception)
What it exploitsAutomatic cookie attachmentUnsanitized outputInvisible framed content
Primary defenseCSRF tokens, SameSite cookiesOutput encoding, CSPX-Frame-Options, CSP frame-ancestors

The takeaway

CSRF forges a request that rides on a victim’s existing authenticated session, exploiting the browser’s default behavior of attaching cookies to any request regardless of origin. SameSite cookie settings have closed off much of the easy attack surface by default, but unique per-session CSRF tokens on state-changing requests remain the most reliable defense, and are worth keeping even on sites that also set SameSite=Strict.

Chisato Chisato · · 5 min read

What Is Session Fixation?

Session fixation tricks a victim into using an attacker-known session ID, so logging in hands the attacker an authenticated session too.

#Security #Authentication #Web Development
Chisato Chisato · · 4 min read

The OAuth PKCE Flow Explained

PKCE hardens the OAuth authorization code flow against interception, and is now recommended for every client type, not just mobile and single-page apps.

#Security #Authentication #Web Development