CSRF — the email update

Cross-Site Request Forgery
account settings — email
Email address: victim@example-app.com
POST /csrf/lab23/email.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

email=<whatever-the-form-carried>

Read it in repeater: the action traveled from the query string into the POST body — that's the only change. There is still no token, no nonce, nothing user-specific. Empowerment note: defensive request shape does not matter if the request is unauthenticated-by-anything-but-cookies.

Method — repeater inspect, POST-edition POC
  1. Locate the update request: submit the app's own form once, find it in the proxy, send it to repeater. Read the body — here it is email=… — and confirm (again) that no token binds it.
  2. Upgrade the POC template from Lab 22 — three touches: method="POST"; action moves to the email endpoint (path only — strip any leftover query from the old booleans, good practice to avoid stale params floating in the action URL); the hidden input's name becomes the body field (email) and its value the attacker address.
  3. The submit button is cosmetic — its label or name can be anything ("Send", "CSRF POC"); the body only carries the real field.
  4. Fire it in a second browser logged to account B: refresh the account page → the attacker's email is set. Framed for impact: forced email swap pre-stages password-reset control — report at the criticality of the action.
  5. Where these live: private programs and older, rarely-visited assets. Less common on bug bounty nowadays, still bread-and-butter on pen tests — and a natural chaining component (e.g. CSRF + self-XSS: force a state change that makes your self-XSS render in someone else's session — its own lab later in this category).
Spoiler — the POST POC, verbatim
<form method="POST" action="https://stuxnet.pro/csrf/lab23/email.php">
  <input type="hidden" name="email" value="attacker@hacker.com">
  <button type="submit">CSRF POC</button>
</form>

Body field = the name; the takeover = the value. Host anywhere reachable over HTTPS, cross-account ritual as in Lab 22. Sanity-check with curl first if you like: curl -X POST https://stuxnet.pro/csrf/lab23/email.php --data-urlencode 'email=attacker@hacker.com' — the endpoint accepts the request with no credentials because there is nothing to present.

Spoiler — why this crosses sites without breaking the same-origin policy

SOP governs reading responses — a cross-site form POST sends just fine; the attacker never needs to see the reply (the redirect makes the browser land on the app anyway). That gap is what CSRF rides on for every method: trigger the request cross-site, don't wait for the answer. POST-only, tokened, header-tokened — each defense narrows what a cross-site trigger can force; that escalation ladder is the rest of this category.