Cross-Site Request Forgery (CSRF)
What is Cross-Site Request Forgery (CSRF)?
Cross-Site Request Forgery (CSRF) is a web security vulnerability that tricks authenticated users into executing unwanted actions on a web application without their knowledge or consent. CSRF attacks exploit the trust that a web application has in a user's browser, leveraging the user's active session to perform actions on their behalf.
Key Characteristics
- Session-based: Requires an active user session
- Unauthorized actions: Performs actions without user consent
- Cross-site execution: Attack originates from a different site
- State-changing operations: Typically affects data modification
- No data theft: Primarily for action execution, not data extraction
How CSRF Works
Attack Flow
graph TD
A[Attacker] -->|1. Crafts malicious website| B[Malicious Site]
B -->|2. Tricks victim to visit| C[Victim]
C -->|3. Visits malicious site| B
B -->|4. Malicious site sends forged request| D[Target Website]
D -->|5. Executes action using victim's session| D
D -->|6. Action completed| A
Technical Mechanism
- Victim Authentication: User logs into target website
- Session Establishment: Browser stores authentication cookies
- Attack Preparation: Attacker crafts malicious website/page
- Victim Trickery: Attacker lures victim to malicious site
- Request Forgery: Malicious site sends forged request to target
- Session Exploitation: Target website executes request using victim's session
- Action Execution: Unwanted action is performed
CSRF Attack Vectors
Common Attack Methods
| Vector | Description | Example |
|---|---|---|
| HTML Forms | Hidden forms that auto-submit | <form action="https://bank.com/transfer" method="POST"> |
| Image Tags | Images with malicious src attributes | <img src="https://bank.com/transfer?to=attacker&amount=1000" /> |
| JavaScript | Scripts that send requests | fetch('https://bank.com/transfer', {method: 'POST', body: 'to=attacker&amount=1000'}) |
| CSS | Stylesheets with malicious URLs | background: url('https://bank.com/transfer?to=attacker&amount=1000') |
| Iframes | Hidden iframes that load target site | <iframe src="https://bank.com/transfer?to=attacker&amount=1000"></iframe> |
| XMLHttpRequest | AJAX requests to target site | xhr.open('POST', 'https://bank.com/transfer', true) |
| Link Tags | Links with malicious href attributes | <a href="https://bank.com/transfer?to=attacker&amount=1000">Click me</a> |
Real-World Examples
- Bank Transfers: Unauthorized money transfers
- Password Changes: Changing user passwords without consent
- Email Settings: Modifying email preferences
- Social Media: Posting content on user's behalf
- E-commerce: Changing shipping addresses
- Account Settings: Modifying user profile information
- Administrative Actions: Changing system configurations
CSRF Exploitation Techniques
1. Basic CSRF with HTML Form
Attack Scenario: Unauthorized bank transfer
Malicious HTML:
<!-- Hidden form that auto-submits -->
<form action="https://bank.com/transfer" method="POST" id="csrfForm">
<input type="hidden" name="to" value="attacker_account" />
<input type="hidden" name="amount" value="1000" />
<input type="hidden" name="currency" value="USD" />
</form>
<script>
// Auto-submit the form when page loads
document.getElementById('csrfForm').submit();
</script>
Process:
- Attacker hosts malicious page with hidden form
- Victim visits malicious page while logged into bank
- Form auto-submits to bank website
- Bank processes transfer using victim's session
- Money transferred to attacker's account
2. CSRF with Image Tag
Attack Scenario: Changing user email settings
Malicious HTML:
<!-- Image tag with malicious GET request -->
<img src="https://email.com/settings?email=attacker@evil.com&action=change" width="0" height="0" />
Process:
- Attacker crafts page with hidden image
- Victim visits page while logged into email service
- Browser attempts to load image, sending GET request
- Email service processes request and changes email
- Attacker can now reset password
3. CSRF with AJAX
Attack Scenario: Social media post creation
Malicious JavaScript:
// AJAX request to create social media post
fetch('https://social.com/api/posts', {
method: 'POST',
credentials: 'include', // Include cookies
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: 'Check out this amazing site! https://evil.com',
privacy: 'public'
})
});
Process:
- Attacker crafts page with malicious JavaScript
- Victim visits page while logged into social media
- JavaScript sends POST request to social media API
- Social media creates post using victim's account
- Malicious content is posted publicly
4. CSRF with Flash (Legacy)
Attack Scenario: Legacy system exploitation
Malicious Flash:
// Flash-based CSRF attack
var request:URLRequest = new URLRequest("https://legacy.com/admin?action=delete&id=1");
request.method = URLRequestMethod.GET;
navigateToURL(request, "_self");
Process:
- Attacker crafts malicious Flash object
- Victim visits page with Flash content
- Flash sends request to legacy system
- Legacy system processes request using victim's session
- Administrative action is executed
CSRF Prevention Methods
1. CSRF Tokens
Principle: Include unique, unpredictable tokens in each request.
Implementation:
<!-- Server includes CSRF token in form -->
<form action="/transfer" method="POST">
<input type="hidden" name="csrf_token" value="UNIQUE_TOKEN_PER_SESSION" />
<input type="text" name="to" />
<input type="number" name="amount" />
<button type="submit">Transfer</button>
</form>
Server-Side Validation:
// Node.js example
app.post('/transfer', (req, res) => {
const sessionToken = req.session.csrfToken;
const requestToken = req.body.csrf_token;
if (sessionToken !== requestToken) {
return res.status(403).send('CSRF token mismatch');
}
// Process legitimate request
});
2. SameSite Cookie Attribute
Principle: Restrict cookie sending to same-site requests.
Implementation:
Set-Cookie: sessionId=abc123; SameSite=Strict; Secure; HttpOnly
Set-Cookie: sessionId=abc123; SameSite=Lax; Secure; HttpOnly
SameSite Options:
- Strict: Cookies only sent in first-party context
- Lax: Cookies sent with top-level navigations (default in modern browsers)
- None: Cookies sent with all cross-site requests (requires Secure)
3. Double Submit Cookie
Principle: Verify token in both cookie and request parameter.
Implementation:
// Client-side: Read cookie and include in request
const csrfToken = document.cookie.match(/csrfToken=([^;]+)/)[1];
fetch('/api/transfer', {
method: 'POST',
headers: {
'X-CSRF-Token': csrfToken
},
body: JSON.stringify({to: 'recipient', amount: 100})
});
Server-Side Validation:
// Node.js example
app.post('/api/transfer', (req, res) => {
const cookieToken = req.cookies.csrfToken;
const headerToken = req.headers['x-csrf-token'];
if (cookieToken !== headerToken) {
return res.status(403).send('CSRF token mismatch');
}
// Process legitimate request
});
4. Custom Request Headers
Principle: Require custom headers for state-changing requests.
Implementation:
// Client-side: Add custom header
fetch('/api/transfer', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-Token': 'UNIQUE_TOKEN'
},
body: JSON.stringify({to: 'recipient', amount: 100})
});
Server-Side Validation:
// Node.js example
app.post('/api/transfer', (req, res) => {
if (!req.headers['x-requested-with'] ||
req.headers['x-requested-with'] !== 'XMLHttpRequest') {
return res.status(403).send('Invalid request');
}
// Process legitimate request
});
5. Origin/Referer Header Validation
Principle: Verify request origin matches expected domain.
Implementation:
// Node.js example
app.post('/transfer', (req, res) => {
const origin = req.headers.origin || req.headers.referer;
const expectedOrigin = 'https://bank.com';
if (!origin || !origin.startsWith(expectedOrigin)) {
return res.status(403).send('Invalid origin');
}
// Process legitimate request
});
6. CAPTCHA
Principle: Require human interaction for sensitive actions.
Implementation:
<form action="/transfer" method="POST">
<input type="hidden" name="csrf_token" value="UNIQUE_TOKEN" />
<div class="g-recaptcha" data-sitekey="SITE_KEY"></div>
<button type="submit">Transfer</button>
</form>
CSRF in Modern Web Applications
Single-Page Applications (SPAs)
Challenges:
- API-driven: Heavy use of AJAX requests
- State management: Complex session handling
- CORS: Cross-Origin Resource Sharing configuration
- Token management: Secure storage of CSRF tokens
Best Practices:
- Use CSRF tokens with API requests
- Implement SameSite cookies
- Validate Origin/Referer headers
- Use custom request headers
- Secure token storage (not in localStorage)
Example (React with CSRF):
import { useState, useEffect } from 'react';
function TransferForm() {
const [csrfToken, setCsrfToken] = useState('');
useEffect(() => {
// Fetch CSRF token from server
fetch('/api/csrf-token')
.then(res => res.json())
.then(data => setCsrfToken(data.token));
}, []);
const handleSubmit = (e) => {
e.preventDefault();
fetch('/api/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify({
to: e.target.to.value,
amount: e.target.amount.value
})
});
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="to" placeholder="Recipient" />
<input type="number" name="amount" placeholder="Amount" />
<button type="submit">Transfer</button>
</form>
);
}
APIs and Microservices
Challenges:
- Stateless authentication: JWT and token-based auth
- Multiple services: Consistent CSRF protection across services
- Third-party clients: External applications accessing APIs
- Mobile clients: Native apps consuming APIs
Best Practices:
- Use SameSite cookies for session management
- Implement token-based CSRF protection
- Validate Origin/Referer headers
- Use short-lived tokens for sensitive operations
- Implement rate limiting for API endpoints
Example (API Gateway CSRF Protection):
// API Gateway middleware
app.use((req, res, next) => {
// Skip CSRF for GET requests
if (req.method === 'GET') return next();
// Validate CSRF token for state-changing requests
const csrfToken = req.headers['x-csrf-token'];
const sessionToken = req.cookies.csrfToken;
if (!csrfToken || csrfToken !== sessionToken) {
return res.status(403).json({error: 'CSRF token validation failed'});
}
next();
});
Serverless Applications
Challenges:
- Stateless functions: No persistent server-side state
- Event-driven: Multiple trigger sources
- Third-party services: Integration with external systems
- Cold starts: Performance considerations
Best Practices:
- Use SameSite cookies for authentication
- Implement token validation in each function
- Validate event sources for sensitive operations
- Use short-lived credentials for external services
- Implement request signing for critical operations
Example (AWS Lambda CSRF Protection):
// Lambda function with CSRF protection
exports.handler = async (event) => {
// Parse request
const request = JSON.parse(event.body);
const csrfToken = request.csrfToken;
const sessionToken = event.cookies.find(c => c.name === 'csrfToken').value;
// Validate CSRF token
if (csrfToken !== sessionToken) {
return {
statusCode: 403,
body: JSON.stringify({error: 'CSRF token validation failed'})
};
}
// Process legitimate request
return {
statusCode: 200,
body: JSON.stringify({message: 'Action completed'})
};
};
CSRF Testing and Detection
Manual Testing Techniques
- Basic Test:
<form action="https://target.com/change-password" method="POST"> <input type="hidden" name="new_password" value="hacked123" /> </form> <script>document.forms[0].submit();</script> - Image Tag Test:
<img src="https://target.com/delete-account" width="0" height="0" /> - AJAX Test:
fetch('https://target.com/api/settings', { method: 'POST', credentials: 'include', body: JSON.stringify({email: 'attacker@evil.com'}) }); - GET Request Test:
<iframe src="https://target.com/transfer?to=attacker&amount=1000"></iframe> - Flash Test (Legacy):
<object type="application/x-shockwave-flash" data="csrf.swf"></object>
Automated Testing Tools
- Burp Suite: Web application security testing
- OWASP ZAP: Zed Attack Proxy
- CSRFTester: Specialized CSRF testing tool
- SQLMap: Can test for CSRF in some contexts
- Browser Developer Tools: Manual request crafting
- Postman: API request testing
- curl: Command-line request testing
Code Analysis Techniques
- Token Analysis: Check for CSRF token implementation
- Header Analysis: Verify SameSite cookie attributes
- Request Analysis: Check for state-changing GET requests
- Origin Validation: Verify Origin/Referer header checks
- Session Analysis: Check session management practices
- Framework Analysis: Verify built-in CSRF protections
- Configuration Review: Check security headers and settings
CSRF Case Studies
Case Study 1: Major Social Network CSRF
Incident: A popular social network had CSRF vulnerabilities in multiple endpoints.
Attack Details:
- Vulnerable endpoints for account settings changes
- No CSRF tokens on sensitive forms
- Attackers crafted malicious pages with auto-submitting forms
- Victims unknowingly changed account settings
- Attack affected millions of users
Impact:
- Unauthorized account modifications
- Privacy settings changes
- Email address changes
- Password reset capabilities
- Reputational damage
Lessons Learned:
- Critical importance of CSRF tokens on all state-changing requests
- Need for comprehensive security testing
- Value of security headers like SameSite cookies
- Importance of framework-level protections
- Need for regular security audits
Case Study 2: Online Banking CSRF
Incident: A major bank had CSRF vulnerabilities in money transfer functionality.
Attack Details:
- Money transfer endpoint vulnerable to CSRF
- No CSRF protection on transfer API
- Attackers crafted malicious pages with transfer requests
- Victims unknowingly sent money to attacker accounts
- Attack affected thousands of customers
Impact:
- Financial losses for customers
- Bank reputation damage
- Regulatory fines
- Increased customer support costs
- Legal liabilities
Lessons Learned:
- Critical need for CSRF protection in financial applications
- Importance of multi-factor authentication for sensitive operations
- Value of transaction verification mechanisms
- Need for fraud detection systems
- Importance of secure development practices
Case Study 3: E-commerce CSRF
Incident: A popular e-commerce platform had CSRF vulnerabilities in checkout process.
Attack Details:
- Checkout process vulnerable to CSRF
- No CSRF tokens in payment forms
- Attackers crafted malicious pages that modified cart contents
- Victims unknowingly purchased attacker-selected items
- Attack affected thousands of transactions
Impact:
- Financial losses for customers
- Inventory manipulation
- Customer trust erosion
- Increased chargeback rates
- Reputational damage
Lessons Learned:
- Need for CSRF protection in all e-commerce workflows
- Importance of order verification processes
- Value of secure payment processing
- Need for fraud monitoring systems
- Importance of secure coding practices
CSRF and Compliance
Regulatory Implications
CSRF vulnerabilities can lead to compliance violations with various regulations:
- PCI DSS: Payment Card Industry Data Security Standard
- Requires protection of payment card data
- Mandates secure coding practices
- Requires regular vulnerability scanning
- GDPR: General Data Protection Regulation
- Requires protection of personal data
- Mandates data breach notification
- Imposes significant fines for non-compliance
- HIPAA: Health Insurance Portability and Accountability Act
- Requires protection of health information
- Mandates security risk assessments
- Requires implementation of security measures
- GLBA: Gramm-Leach-Bliley Act
- Requires protection of financial information
- Mandates security controls for financial institutions
- Requires customer data protection
- PSD2: Payment Services Directive 2
- Requires strong customer authentication
- Mandates secure payment processing
- Requires fraud prevention measures
Compliance Requirements
| Regulation | Requirement | CSRF Prevention |
|---|---|---|
| PCI DSS | Protect cardholder data | CSRF tokens, SameSite cookies |
| GDPR | Protect personal data | Secure coding, CSRF protection |
| HIPAA | Protect health information | CSRF tokens, secure development |
| GLBA | Protect financial information | CSRF protection, secure coding |
| PSD2 | Secure payment processing | CSRF tokens, strong authentication |
CSRF in the OWASP Top 10
OWASP Top 10 2021: CSRF is part of A01:2021 - Broken Access Control, which is ranked #1 in the OWASP Top 10 Web Application Security Risks.
Key Points:
- Prevalence: CSRF remains a common vulnerability
- Exploitability: Can be exploited with minimal technical knowledge
- Impact: Can lead to unauthorized actions and data modification
- Detectability: Relatively easy to detect with proper testing
- Business Impact: Can cause financial and reputational damage
OWASP Recommendations:
- Use CSRF tokens for all state-changing requests
- Implement SameSite cookie attributes
- Validate Origin/Referer headers
- Use custom request headers for sensitive operations
- Avoid state-changing GET requests
- Implement CAPTCHA for sensitive actions
- Use security-focused frameworks with built-in CSRF protection
- Regular security testing to identify vulnerabilities
Advanced CSRF Techniques
1. Login CSRF
Technique: Tricking users into logging into attacker-controlled accounts.
Attack Scenario:
- Attacker creates account on target website
- Attacker crafts malicious login page
- Victim visits page and logs in
- Victim is logged into attacker's account
- Victim enters sensitive information
- Attacker accesses victim's data
Prevention:
- Include CSRF tokens in login forms
- Use SameSite cookies for session management
- Implement additional authentication factors
- Educate users about phishing risks
2. CSRF with CORS Misconfiguration
Technique: Exploiting improper CORS configuration.
Attack Scenario:
- Target site has misconfigured CORS policy
- Attacker crafts malicious page with AJAX request
- Victim visits page while logged into target site
- Browser allows cross-origin request due to CORS misconfiguration
- Request executes with victim's credentials
Prevention:
- Proper CORS configuration: Only allow trusted origins
- Validate Origin headers: On the server side
- Use CSRF tokens: Even with CORS
- Implement SameSite cookies
3. CSRF with WebSockets
Technique: Exploiting WebSocket connections.
Attack Scenario:
- Target site uses WebSockets for real-time updates
- Attacker crafts malicious page that connects to WebSocket
- Victim visits page while logged into target site
- Malicious WebSocket messages sent with victim's session
- Unauthorized actions performed
Prevention:
- Validate WebSocket connections: Check Origin headers
- Use CSRF tokens: For WebSocket handshake
- Implement authentication: For WebSocket connections
- Use SameSite cookies: For session management
4. CSRF with Server-Side Request Forgery (SSRF)
Technique: Combining CSRF with SSRF for internal attacks.
Attack Scenario:
- Target site has CSRF vulnerability
- Target site also has SSRF vulnerability
- Attacker crafts malicious page that triggers CSRF
- CSRF request includes SSRF payload
- Internal systems are compromised
Prevention:
- Implement CSRF protection: For all external-facing endpoints
- Implement SSRF protection: For internal requests
- Use network segmentation: Isolate internal systems
- Implement request validation: For all inputs
5. CSRF with Clickjacking
Technique: Combining CSRF with clickjacking for stealthy attacks.
Attack Scenario:
- Target site has CSRF vulnerability
- Attacker crafts malicious page with transparent iframe
- Victim visits page and clicks on disguised elements
- Clicks trigger CSRF requests
- Unauthorized actions performed without victim awareness
Prevention:
- Implement X-Frame-Options header: Prevent iframe embedding
- Implement Content Security Policy: Restrict framing
- Implement CSRF protection: For all state-changing requests
- Use SameSite cookies: For session management
CSRF Mitigation Strategies
Defense in Depth Approach
- Input Layer:
- Validate all user input
- Implement CSRF tokens
- Use SameSite cookies
- Processing Layer:
- Validate Origin/Referer headers
- Check CSRF tokens
- Implement request validation
- Output Layer:
- Set secure cookie attributes
- Implement security headers
- Use secure coding practices
- Session Layer:
- Implement proper session management
- Use short-lived sessions
- Implement session expiration
- Monitoring Layer:
- Monitor for suspicious activity
- Implement rate limiting
- Detect and block malicious requests
Secure Development Lifecycle
- Design Phase:
- Threat modeling for CSRF risks
- Security requirements definition
- Secure architecture design
- Development Phase:
- Implement CSRF protection
- Use security-focused frameworks
- Follow secure coding practices
- Testing Phase:
- CSRF vulnerability scanning
- Penetration testing
- Manual security testing
- Code review with security focus
- Deployment Phase:
- Secure configuration
- Security headers implementation
- CSRF protection validation
- Web Application Firewall (WAF) configuration
- Maintenance Phase:
- Regular security updates
- Patch management
- Security monitoring
- Incident response planning
- User education
Emerging Technologies
- SameSite Cookies by Default:
- Modern browsers default to SameSite=Lax
- Reduces CSRF attack surface
- Requires Secure attribute for cross-site cookies
- Trusted Types:
- Modern API to prevent DOM-based attacks
- Can help prevent CSRF in some contexts
- Enforces safe DOM manipulation
- Web Authentication (WebAuthn):
- Strong authentication mechanism
- Resistant to CSRF attacks
- Uses public-key cryptography
- Content Security Policy (CSP):
- Restricts sources of executable scripts
- Can prevent some CSRF attack vectors
- Provides additional security layer
- Automatic CSRF Protection:
- Modern frameworks with built-in CSRF protection
- Automatic token generation and validation
- Reduced developer burden
Conclusion
Cross-Site Request Forgery (CSRF) remains a significant and pervasive web security threat that exploits the trust web applications place in user browsers. Despite being a well-known vulnerability for many years, CSRF continues to affect modern web applications, including single-page applications, APIs, and serverless architectures.
The unique characteristics of CSRF make it particularly dangerous:
- Session exploitation: Leverages active user sessions
- Unauthorized actions: Performs actions without user consent
- Cross-site execution: Originates from malicious third-party sites
- State-changing operations: Typically affects data modification
- Difficult detection: Users often unaware of the attack
Preventing CSRF requires a comprehensive, multi-layered approach that includes:
- CSRF tokens: Unique tokens for each request
- SameSite cookies: Restricting cookie sending to same-site requests
- Origin/Referer validation: Verifying request origins
- Custom request headers: Requiring specific headers for sensitive operations
- Security headers: Implementing X-Frame-Options, CSP, etc.
- Secure coding practices: Following security guidelines
- Regular testing: Identifying and fixing vulnerabilities
- Developer education: Training on CSRF risks and prevention
As web technologies continue to evolve with new authentication methods, API-driven architectures, and serverless computing, the threat landscape for CSRF will continue to change. Developers and security professionals must stay vigilant and implement comprehensive security measures to protect against these evolving threats.
The key to effective CSRF prevention lies in secure development practices, continuous monitoring, proactive security testing, and a defense-in-depth approach that adapts to the modern web landscape. By understanding the mechanisms, techniques, and prevention methods of CSRF, organizations can significantly reduce their risk and protect their users from these pervasive and damaging attacks.
Cross-Origin Resource Sharing (CORS)
Security mechanism that enables controlled access to resources located outside of a given domain, relaxing the Same-Origin Policy.
Cross-Site Scripting (XSS)
Cross-Site Scripting (XSS) is a web security vulnerability that allows attackers to inject malicious scripts into web pages viewed by other users, enabling data theft, session hijacking, and account compromise.
