đŸ›Ąïž Application Security CheatSheet

CSRF (Cross-Site Request Forgery) Deep Dive

CSRF happens when a website accidentally lets an attacker trigger actions as you because your browser automatically includes your login cookies on requests to that site.

Practical note: CSRF usually ships when teams rely on ‘same-site cookies’ as a magic shield — then one exception (or legacy browser/client) breaks the assumption.

Key idea: CSRF is not “stealing a password”. It’s abusing the browser’s automatic credential sending (cookies) to make state changes without the user’s real intent.
This page is for learning and It explains CSRF concepts and defensive validation without copy/paste exploit recipes.

Deep reason CSRF exists (why the browser behaves this way)

The web was designed so browsers can automatically maintain sessions using cookies. When you’re logged into bank.example, your browser will attach session cookies to requests to bank.example—even if those requests were initiated from another site (a link, a form, an image, or a script-driven request).

experienced framing: CSRF is a confused-deputy problem—your browser becomes the deputy that submits authenticated requests on your behalf.

First principles mental model

Think of CSRF as a three-part mismatch:

  1. Authentication: the server trusts the session cookie.
  2. Authorization: the user is allowed to perform the action.
  3. Intent verification: the server fails to verify that the request came from the site’s own UI and was deliberate.

CSRF happens when you have cookie-based auth and a state-changing endpoint, and the server does not demand an additional unforgeable signal of intent (like a CSRF token).

When CSRF is in-scope (and when it isn’t)

Typically at risk

Often not CSRF (or lower risk)

Important nuance: Even token-based APIs can become CSRF-like if the token is stored in a cookie and auto-sent, or if the site uses “remember me” cookies.

Vulnerable vs secure code patterns (Node.js)

Vulnerable pattern (cookie session + no CSRF protection)

// Node/Express (example)
// Cookie-based session (e.g., express-session) means browser auto-sends cookies

app.post("/account/email", async (req, res) => {
  // ❌ Missing CSRF protection: server only checks "is logged in"
  if (!req.user) return res.status(401).json({ error: "Not authenticated" });

  const newEmail = String(req.body.email || "");
  await users.updateEmail(req.user.id, newEmail);

  res.json({ ok: true });
});
Why this is risky: if a logged-in user’s browser can be tricked into sending this POST, the cookie makes it look legitimate.

Secure pattern (CSRF token + SameSite)

// ✅ Defensive pattern using csurf (token-based CSRF protection)
// Also ensure cookies are configured with SameSite and Secure.

import express from "express";
import cookieParser from "cookie-parser";
import csrf from "csurf";

const app = express();
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.use(cookieParser());

// Example cookie session cookie settings (conceptual)
// res.cookie("sid", value, { httpOnly: true, secure: true, sameSite: "lax" });

const csrfProtection = csrf({
  cookie: {
    key: "__Host-csrf",
    httpOnly: true,
    secure: true,
    sameSite: "lax",
    path: "/"
  }
});

// Serve token for forms/SPA
app.get("/csrf-token", csrfProtection, (req, res) => {
  res.json({ csrfToken: req.csrfToken() });
});

// Protect state-changing routes
app.post("/account/email", csrfProtection, async (req, res) => {
  if (!req.user) return res.status(401).json({ error: "Not authenticated" });

  const newEmail = String(req.body.email || "");
  await users.updateEmail(req.user.id, newEmail);

  res.json({ ok: true });
});
Why this holds: the attacker can cause a request to be sent, but cannot mint a valid CSRF token bound to the user’s session/context. SameSite reduces cross-site cookie sending, and CSRF tokens close the remaining gaps.

Modern mitigations and how they fit together

1) SameSite cookies (baseline defense)

experienced line: SameSite is great, but it’s not a universal substitute for CSRF tokens because real apps have exceptions (cross-site flows, legacy browsers, special endpoints).

2) CSRF tokens (primary enforcement for unsafe methods)

3) Origin/Referer checks (defense-in-depth)

4) Re-authentication / step-up verification (for high-risk actions)

Production mindset: Use SameSite + CSRF tokens for broad coverage, then add step-up for critical operations.

Types / variants (and why they differ)

1) Classic form-based CSRF

Works when a server accepts form-like requests and relies only on cookies for auth. The key issue is missing intent verification.

2) CSRF against JSON endpoints

Many JSON endpoints are safer because browsers impose restrictions on cross-site requests that use non-simple headers/content-types. But risk returns if the endpoint accepts “simple” encodings or if the app exposes a CSRF token improperly.

3) Login CSRF

The victim is tricked into being logged into the attacker’s account on the target site. Impact is usually session confusion (victim performs actions under attacker’s session) rather than direct money movement.

4) State-changing GET (a design bug that enables CSRF)

If a GET request changes state (e.g., “/delete?id=...”), then many browser behaviors make it easier to trigger accidentally. The fix is: GET must be idempotent; use POST with CSRF defenses for changes.

Detection workflow (experienced-style, systematic)

This avoids “try random stuff” and instead confirms the exact preconditions for CSRF.

Step A — Identify state-changing endpoints

Step B — Confirm the auth mechanism

Step C — Look for missing intent verification

What you’re proving: “A state change can occur with only the victim’s ambient credentials, without a same-site proof of intent.”

Safe validation workflow (defensive verification)

Goal: confirm CSRF risk without providing exploit instructions. Use a controlled test account and minimal-impact actions.
  1. Baseline: capture a legitimate request that changes state (e.g., update a low-risk preference).
  2. Check defenses: identify whether a CSRF token is present/required and whether the app enforces SameSite.
  3. Negative test: confirm that the server rejects unsafe requests when the token is missing/invalid (expect 403 or equivalent).
  4. Cross-origin reasoning: verify the server requires a same-site signal (token and/or origin check) for unsafe methods.
  5. Document evidence: request/response showing missing enforcement, plus the observed state change (minimal and reversible).
Interview-safe phrasing: “I validate CSRF by proving missing intent verification on cookie-authenticated state changes, using low-risk reversible actions and capturing clear before/after evidence.”

Exploitation progression (attacker mindset)

This explains how real attackers think about CSRF without giving copy/paste steps. The goal is to understand the decision process.

Phase 1: Find actions that matter

Phase 2: Check whether cookies are the auth mechanism

Phase 3: Look for missing intent verification

Phase 4: Increase impact via chaining

Interview takeaway: CSRF exploitation is about finding high-impact state changes that rely only on ambient credentials, then confirming missing intent verification and inconsistent defenses.

Tricky edge cases & bypass patterns (what attackers look for)

Reality check: Saying “we set SameSite=Lax so we’re done” is often wrong in real enterprises because of legitimate cross-site flows and legacy clients.

Confidence levels (how sure are you?)

ConfidenceWhat you observedWhat you can claim
Low Cookie-authenticated state change exists, but defenses are unclear or inconsistent across environments “Potential CSRF exposure; needs verification of token enforcement and SameSite behavior”
Medium State-changing endpoint lacks token enforcement or accepts unsafe requests in some paths “Likely CSRF due to missing intent verification on a cookie-authenticated endpoint”
High Repeatable evidence: missing/invalid token accepted (or no token at all) plus confirmed state change (minimal/reversible) “Confirmed CSRF risk with demonstrated state change under ambient authentication”

Fixes that actually hold in production

1) Make cookies safer

2) Enforce CSRF tokens for unsafe methods

3) Add origin checks (defense-in-depth)

4) Step-up for critical actions

Best-practice combo: SameSite (baseline) + CSRF tokens (primary) + origin checks (extra) + step-up (critical operations).

Regression prevention (how to prevent regressions)

Interview-ready answers (60-second + 2-minute)

60-second answer

CSRF is when a user’s browser performs a state-changing action on a site using the user’s existing session cookies, without a reliable same-site proof of intent. It happens because cookies are sent automatically. The fix is to require intent verification on unsafe methods—CSRF tokens—and to harden cookies with SameSite and Secure. For high-risk actions, add re-auth or step-up verification. I validate it by checking cookie-based auth plus missing token/origin enforcement, using reversible low-risk actions and clear before/after evidence.

2-minute answer

I model CSRF as an “ambient authority” problem: cookies are automatically attached to requests, so the server must verify intent, not just authentication. I start by enumerating state-changing endpoints and confirming the auth mechanism. If the endpoint relies on cookies and doesn’t require a CSRF token (or validates it incorrectly), it’s vulnerable. SameSite helps a lot, but it’s not a universal substitute because real apps often need cross-site flows (SSO/OAuth), and legacy clients can behave differently. So production-grade defense is SameSite as baseline plus CSRF tokens for unsafe methods, optionally origin checks as defense-in-depth, and step-up verification for critical actions. Then I prevent regressions with tests that assert missing/invalid tokens are rejected and with a code review rule that unsafe cookie-auth endpoints must show CSRF enforcement.

Checklist (quick review)

Remediation playbook

  1. Contain: protect the highest-risk endpoints first (email/password change, payouts, approvals).
  2. Fix baseline: set session cookies to Secure + HttpOnly + appropriate SameSite (Lax/Strict where possible).
  3. Implement tokens: add CSRF middleware and enforce on all unsafe methods by default.
  4. Harden flows: add origin checks and step-up verification for critical actions.
  5. Scope: search for endpoints outside the main router stack (admin, legacy, internal tools) that may skip middleware.
  6. Test: add integration tests asserting missing/invalid token returns 403.
  7. Monitor: alert on CSRF validation error spikes; review blocked attempts and broken clients.

Interview Questions & Answers (Easy → Hard)

How to use: Start with a simple explanation (10–15 seconds), then add depth (1–2 minutes): root cause, edge cases, and trade-offs.

Easy

  1. What is CSRF?
    A: Plain: It’s when your browser performs an action on a site as you, without your intended consent. Deep: It happens because cookies are sent automatically, so the server must verify intent with CSRF tokens and safer cookie settings.
  2. Why do cookies matter for CSRF?
    A: Plain: Cookies “ride along” automatically. Deep: That makes them ambient authority—requests can look authenticated even if initiated from another site.
  3. Is CSRF possible if an API uses an Authorization header token?
    A: Plain: Usually no, because the browser won’t auto-send that header cross-site. Deep: Risk returns if the token is stored in a cookie or if the app relies on cookies for any state-changing actions.
  4. What is the best primary defense?
    A: Plain: CSRF tokens on state-changing requests. Deep: Tokens provide a same-site proof of intent; combine with SameSite cookies for strong coverage.
  5. What does SameSite do?
    A: Plain: It limits when cookies are sent in cross-site requests. Deep: Lax/Strict reduce cross-site cookie sending, lowering CSRF risk, but real apps sometimes need exceptions (SSO/OAuth flows).
  6. Why is “GET should not change state” relevant to CSRF?
    A: Plain: GET is easy to trigger. Deep: If GET changes state, many normal browser behaviors can cause unintended actions; use POST with CSRF protection for changes.
  7. Follow-up: Is a hidden form field enough?
    A: Plain: Not unless it’s a real CSRF token. Deep: The value must be unpredictable and server-validated, bound to the session/user context.

Medium

  1. How do you validate CSRF in an interview-safe way?
    A: Plain: I check if state changes rely on cookies and whether tokens/origin checks are enforced. Deep: I capture a baseline request, confirm defenses, and ensure missing/invalid tokens are rejected—using low-risk reversible actions and clear before/after evidence.
  2. Scenario: A site has SameSite=Lax. Is CSRF solved?
    A: Plain: It’s reduced, not guaranteed solved. Deep: Cross-site flows and exceptions can re-open risk; tokens provide consistent intent verification across endpoints and clients.
  3. Scenario: A JSON endpoint rejects cross-origin requests. Can it still be CSRF?
    A: Plain: Possibly, depending on what it accepts. Deep: If it accepts simple request formats or relies on cookies without token enforcement, you can still get CSRF-like state changes. Evaluate the server-side enforcement, not only the browser behavior.
  4. What’s “login CSRF”?
    A: Plain: Victim ends up logged into the attacker’s account on the site. Deep: Impact is session confusion—victim actions attach to attacker’s account; mitigations include anti-CSRF on login, session rotation, and confirmation steps.
  5. Follow-up: If you implement tokens, where should they live for a SPA?
    A: Plain: Fetch from same origin and send back in a header. Deep: Keep tokens tied to session and avoid exposing long-lived tokens; store the session cookie HttpOnly; handle token rotation and caching carefully.
  6. Follow-up: Why add origin checks if you already have tokens?
    A: Plain: Defense-in-depth. Deep: Origin checks can catch misconfigurations or endpoints missing middleware; they add an extra same-site signal for unsafe methods.
  7. Scenario: A sensitive endpoint uses POST but still has no CSRF token. What’s your priority fix?
    A: Plain: Add CSRF enforcement for unsafe methods. Deep: Enable middleware by default, ensure SameSite is set appropriately, and add step-up verification if the action is high risk.

Hard

  1. Scenario: The app uses OAuth/SSO and needs SameSite=None. How do you stay safe?
    A: Plain: Rely more on CSRF tokens and strict flow validation. Deep: Use state parameters correctly for OAuth flows, enforce CSRF tokens on app actions, validate Origin on unsafe requests, and apply step-up verification for critical operations.
  2. Scenario: Some routes are protected by CSRF middleware, but admin routes aren’t. Why does this happen?
    A: Plain: Different routers/stacks. Deep: Teams often mount admin/legacy routers without shared middleware. Fix by enforcing CSRF at the framework level by default and requiring explicit opt-out with review.
  3. Scenario: You see a token in requests, but CSRF still works. What are the likely root causes?
    A: Plain: Token isn’t validated properly. Deep: It may not be bound to the session, may be accepted when missing/empty, may be reused across users, or may be bypassed via an alternate route/content-type that skips validation.
  4. Scenario: A “change email” endpoint is protected by tokens, but A tester can still cause damage. How?
    A: Plain: CSRF isn’t the only risk. Deep: If sessions can be stolen (XSS), or if there’s no step-up verification, high-risk actions remain sensitive. Add re-auth/OTP and monitor unusual changes.
  5. Scenario: Multi-subdomain apps share cookies at.example.com. What changes for CSRF?
    A: Plain: Bigger blast radius. Deep: One sub-app can influence another if not isolated. Prefer host-only cookies where possible, segment apps, and treat cross-subdomain requests with the same intent controls.
  6. Scenario: You must support legacy clients that don’t handle SameSite consistently. What’s your strategy?
    A: Plain: Rely on server-side CSRF enforcement. Deep: Tokens and origin checks provide consistent intent verification independent of client quirks; keep SameSite as baseline but don’t assume it’s universal.
  7. Follow-up: How do you prevent regressions at scale?
    A: Plain: Make CSRF protection the default and test it. Deep: Global middleware, integration tests asserting 403 on missing/invalid tokens, and a code review rule for any cookie-auth unsafe endpoint.
  8. Follow-up: How do you explain CSRF impact to a business stakeholder?
    A: Plain: “A user can be tricked into performing actions they didn’t intend.” Deep: Tie impact to concrete outcomes: account changes, unauthorized approvals, fraud workflows; then present layered mitigations and low-friction step-up for critical operations.
  9. Follow-up: What trade-offs exist between SameSite=Strict and user experience?
    A: Plain: Strict can break legitimate navigation. Deep: Cross-site entry points (deep links, SSO returns) may fail; many apps choose Lax + tokens, reserving Strict for the most sensitive surfaces.
Safety note: for understanding + This guide explains concepts and validation strategy without providing exploit recipes.