| Field | Detail |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Type | GraphQL API Vulnerabilities / CSRF |
| Difficulty | Practitioner |
| Objective | Exploit a GraphQL endpoint that accepts x-www-form-urlencoded to perform a CSRF attack that changes the victim's email address |
Performing CSRF Exploits over GraphQL¶
I logged in as wiener:peter. The account page had an email update field:
Submitting an email change generated a POST /graphql/v1 with Content-Type: application/json and no CSRF token:
Testing twice with different addresses — both succeeded:
application/json is normally CSRF-resistant — browsers enforce CORS preflight for cross-origin JSON requests, which blocks CSRF. But form-encoded POST requests are classified as "simple requests" and don't require preflight: a browser sends them cross-origin with session cookies attached. If the endpoint also accepts x-www-form-urlencoded, it inherits the CSRF vulnerability of the weaker content type. A GraphQL mutation over form-encoded POST is structurally identical to a CSRF-vulnerable HTML form — different surface, same browser mechanics.
Changing Content-Type to application/x-www-form-urlencoded and encoding the mutation as form parameters:
query=%0A++++mutation+changeEmail%28%24input%3A+ChangeEmailInput%21%29+...&operationName=changeEmail&variables=%7B%22input%22%3A%7B%22email%22%3A%22miku%40mikumail.com%22%7D%7D
Email changed — the endpoint accepted form-encoded bodies. I right-clicked the request in Burp and selected "Generate CSRF PoC", updating the target email in the payload to the attacker-controlled address:
Hosted the generated HTML on the exploit server and delivered it to the victim. The browser submitted the form with the victim's session cookie, changing their email without any interaction beyond loading the exploit page:
Lab solved