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.
email=… — and confirm (again) that no token binds it.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.<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.
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.
CSRF — the email update
Cross-Site Request Forgery