← Back to all reports

Account Takeover of Any User via Password-Reset Email Injection

Reported May 15, 2026
Severity High
Platform Web
Vulnerability Class Stored Cross-Site Scripting (CWE-79)
Target Type Major US News Publication
Impact Permanent account takeover with captured plaintext password

The Risk

An attacker who knew only a victim's email could take over their news-site account the next time the victim clicked a real password-reset link sent by the publication itself. The attack captured the brand-new password the victim typed, not just a temporary login cookie, which means the attacker could change the email address on the account and lock the original owner out permanently. The victim only ever saw a genuine email from the publication, with no warning that anything was wrong.

The Vulnerability

The forgot-password endpoint accepted a redirect-after-reset value from the request body and stored it as-is. The server then dropped that value verbatim into the link inside the password-reset email it sent to the victim.

Any string the attacker submitted in that field, including a script-execution payload, was rendered into the body of the real email sent from the publication's own infrastructure. The set-password page after reset auto-redirected through the same value, executing whatever the attacker had stored against the now-authenticated session.

The Attack

Inject the payload

The attacker visited the forgot-password page, entered the victim's email, intercepted the outgoing request, and replaced the redirect-after-reset field with a script payload that read the password input from the page DOM and fetched session tokens from the publication's own auth-status endpoint.

A protection layer in front of the site blocked obvious script keywords combined with the "javascript:" scheme. Splitting method names across string concatenation (such as constructing "onload" as "on" + "load") and using alternate constructor syntax slipped past the filter cleanly.

Victim receives a genuine email

The publication sent the victim a real password-reset email from its own mail infrastructure. The reset link inside it carried the attacker's payload as the redirect-after-reset parameter. Nothing about the email looked unusual.

Victim sets a new password

The victim clicked the link, entered a new password on the publication's set-password page, and submitted. The form completed the reset, signed the victim in, then redirected through the attacker's payload. The payload executed on the publication's own origin inside the freshly authenticated session.

Exfiltrate password and session

The payload read the plaintext password from the still-mounted form input, fetched the session tokens from the publication's auth-status endpoint, and sent both to the attacker's collector using a fire-and-forget beacon, completing before the page navigated away.

Replay

The attacker pasted the stolen session cookies into a clean browser and reloaded. The publication's account profile page loaded fully signed in as the victim.

The Impact

  • Full account takeover of any user, starting from only their email address.
  • Captured plaintext password, not just a transient session, which means the attacker can authenticate as the victim, rotate the account's email address using the current-password gated endpoint, and lock the victim out permanently.
  • Session cookies carry a multi-year lifetime and are not invalidated server-side on credential rotation or logout, so even pure session theft persists across the victim's own future password changes.
  • The victim only ever clicks a real, brand-domain email. No phishing infrastructure, no attacker-controlled link in the inbox. The attack is invisible to the victim.

Remediation

  • Strictly validate the redirect-after-reset value against an allowlist of internal paths. Reject any value containing a scheme, host, or non-path characters.
  • Never persist user-supplied URLs into transactional emails without encoding for the rendering context.
  • Invalidate all existing session cookies on credential change and on explicit logout, server-side, by token blacklist or session-id rotation.
  • Require step-up verification on email-address changes, not just current password.
  • Treat the password-reset email template as a high-sensitivity output sink. Static-analysis and template-review controls should cover it.
  • The protection layer in front of the site should not be relied on as the only defence against script injection. Multiple bypass classes were trivially available.