CSRF Attack Prevention Exercise
Understanding the Problem
Cross-Site Request Forgery (CSRF) is like a forged check - someone else trying to make transactions using your signature. In this exercise, we need to:
- Understand how CSRF attacks work in a web application
- Execute a sample CSRF attack to understand the vulnerability
- Implement protection against CSRF attacks
- Verify the protection works
Devising a Plan
- Set up both applications:
- Real application on port 5001
- Malicious application
- Log in as DemoUser to demonstrate vulnerability
- Execute the CSRF attack through malicious app
- Implement CSRF protection
- Verify protection works
Executing the Plan
Step 1: Initial Setup
# Terminal 1 - Malicious App
cd malicious-app
npm install
npm run dev
# Terminal 2 - Real App
cd real-app
npm install
npm run migrate
npm run seed
npm run dev
Step 2: Understanding the Attack
The attack flow works like this:
- User logs into legitimate site at localhost:5001
- User clicks malicious link
- Malicious site uses stored credentials to make requests
- Real site accepts requests thinking they're legitimate
Step 3: Implementing Protection
In real-app/backend/app.js, enable CSRF protection:
// Enable CSRF protection
app.use(csurf({
cookie: {
secure: process.env.NODE_ENV === 'production',
sameSite: process.env.NODE_ENV === 'production' && "Strict",
httpOnly: true
}
}));
In frontend JavaScript files, add CSRF token to requests:
// Add to fetch requests
headers: {
'XSRF-Token': getCookie('XSRF-Token')
}
Verifying the Solution
To verify our protection works:
- Submit tweet in real application - should succeed
- Try submitting through malicious app - should fail
Real World Applications
CSRF protection is crucial in:
- Online Banking: Preventing unauthorized transfers
- Social Media: Protecting post/comment actions
- E-commerce: Securing purchase transactions
- Admin Panels: Protecting administrative actions
Additional Protection Methods
Beyond CSRF tokens, other protection methods include:
- SameSite Cookies: Restrict cookie sending to same-site requests
- Custom Headers: Require custom headers that browsers restrict
- Double Submit Cookies: Compare token in cookie vs request
Common Mistakes to Avoid
- Relying only on checking Referer headers
- Using predictable CSRF tokens
- Not protecting all state-changing endpoints
- Forgetting to validate token presence
Further Learning Resources
- OWASP CSRF Prevention Cheat Sheet
- Web Security Academy CSRF Lessons
- Node.js csurf package documentation
File Structure Reference
real-app/
├── backend/
│ └── app.js // Main server file with CSRF protection
├── frontend/
│ └── js/
│ ├── home.js // Frontend CSRF token handling
│ ├── login.js // Login form protection
│ ├── nav.js // Navigation protection
│ └── tweet-form.js // Tweet submission protection