What is CSRF?
Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker’s choosing.How CSRF Works
A CSRF attack generally requires an internal threat actor to provide insight into the internal workings of the API or system, which makes it one of the more challenging cyber vulnerabilities to mitigate. The attack exploits the trust that a web application has in the user’s browser. If a user is authenticated to a site, their browser automatically sends authentication cookies with every request to that site—even if the request originates from a malicious third-party site.CSRF Attack Example in Normo Unsecure PWA
The application is vulnerable to CSRF attacks because it:- Has no CSRF token protection on forms
- Accepts form submissions without origin validation
- Relies solely on session cookies for authentication
The Attack Setup
The included CSRF exploit (/home/daytona/workspace/source/.student_resources/CSRF/index.html) demonstrates a sophisticated phishing attack:
CSRF Attack - Fake Email Interface
The Attack JavaScript
CSRF Attack Script
Notice how the attack automatically detects the environment (Codespaces vs. local) and adjusts the target URL accordingly. This makes the attack highly portable.
How to Test for CSRF
Create a Malicious Webpage
Create a simple webpage with a duplicate form that declares the
value attribute for each form input. The example in .student_resources/CSRF/index.html is set up as a whale or spear phishing attack targeting a victim with administration-level authorization.Host the Attack Page
Host the malicious page on a different origin (different domain or port):This simulates hosting the attack on a different domain.
Ensure Target is Authenticated
The victim must have an active session on the target application. Log in to the Normo Unsecure PWA before testing.
Execute the Attack
Open the malicious page (e.g.,
http://localhost:5500/index.html) and click the “Click to claim” button.Vulnerable Endpoints
The following endpoints in Normo Unsecure PWA are vulnerable to CSRF:/signup.html - User Registration
/signup.html - User Registration
Vulnerability: Accepts POST requests without CSRF token validation.Impact: Attackers can create unauthorized user accounts, including admin accounts if the attacker knows the required parameters.Attack Vector:
/feedback.html - Feedback Submission
/feedback.html - Feedback Submission
Vulnerability: Accepts feedback without CSRF protection.Impact: Attackers can submit fake feedback or inject malicious content (combined XSS+CSRF attack).Attack Vector:
Any State-Changing Operation
Any State-Changing Operation
Vulnerability: No forms use CSRF tokens.Impact: Any authenticated action can be forced on a victim.
How to Fix CSRF Vulnerabilities
The key to preventing CSRF is implementing the Synchronizer Token Pattern (STP), where a secret and unique value for each request is embedded in forms and verified on the server side.
Implementation with Flask-WTF
The best solution is to use Flask-WTF, which automatically implements CSRF protection:Manual CSRF Token Implementation
If you can’t use Flask-WTF, implement CSRF protection manually:Comprehensive Countermeasures
Implement Synchronizer Token Pattern
Use Flask-WTF or implement CSRF tokens manually. This is the most effective defense against CSRF attacks.The token should be:
- Unpredictable (cryptographically random)
- Unique per session
- Validated on every state-changing request
Use SameSite Cookie Attribute
Configure session cookies with SameSite attribute:
Strict: Cookie only sent for same-site requestsLax: Cookie sent for same-site and top-level navigation
Implement Three-Factor Authentication for Admin Actions
Require additional authentication for sensitive operations:
End-User Education
Train users to:
- Be suspicious of unsolicited emails with links
- Verify URLs before clicking
- Log out after using sensitive applications
- Not click links in emails claiming urgent action
Code Review with Specific Scenarios
Understand how CSRF can be executed in your specific application context:
- Map all state-changing endpoints
- Identify which require authentication
- Ensure all have CSRF protection
- Test with actual attack scenarios
Testing Checklist
Endpoints to Test
Endpoints to Test
Test CSRF protection on all state-changing operations:
- ✅ User registration
- ✅ Login (less critical, but good practice)
- ✅ Password change
- ✅ Email change
- ✅ Profile updates
- ✅ Content submission (feedback, comments)
- ✅ Administrative actions
- ✅ Financial transactions
- ✅ Account deletion
Attack Scenarios to Test
Attack Scenarios to Test
- Basic CSRF: Hidden form auto-submits on page load
- XSS + CSRF: Use XSS to extract CSRF token
- Subdomain attack: Attack from subdomain if SameSite=Lax
- CORS misconfiguration: Exploit permissive CORS policies
Real-World Impact
File Locations
Lines 88-94: Hidden malicious form that exploits CSRF vulnerabilityLines 98-128: JavaScript that detects environment and submits the attackThis file serves as a complete CSRF exploit demonstration, showing how attackers combine social engineering (fake email interface) with technical exploitation.
All POST endpoints lack CSRF protection:
/signup.html- Vulnerable to account creation/feedback.html- Vulnerable to content injection/(login) - Vulnerable to session fixation
References
Flask-WTF Documentation
Official documentation for implementing CSRF protection in Flask applications using the Synchronizer Token Pattern
