Breach report
Stored XSS to account takeover: the web's most common bug class
What happened
Cross-site scripting (XSS) is not a single breach but a persistent vulnerability class — and the most prevalent one on the web. HackerOne reports XSS as "the number one most common vulnerability for bug bounty," and its three main variants together account for roughly a fifth of all reported findings on the platform; MITRE ranks XSS (CWE-79) as #1 on the 2024 CWE Top 25. The mechanism is straightforward: an attacker gets malicious script to execute in another user's browser, in the trusted context of the vulnerable site.
Once that script runs, it can "steal session cookies, log keystrokes, extract confidential data," and act as the victim. In the account-takeover pattern, stolen session tokens or captured credentials let the attacker log in as the victim. HackerOne's own writeup documents a reflected-XSS case on Yelp — possible by manipulating an unescaped cookie value — where the researcher demonstrated full business-account compromise and keystroke logging.
Root cause
The application places untrusted input into an HTML, JavaScript, or attribute context without proper output encoding — CWE-79, a member of OWASP's Injection category. Stored XSS is the most dangerous variant: the payload is persisted server-side (a comment, profile field, filename) and then served to every user who views it, so no lure is needed. The browser cannot distinguish the site's intended markup from injected script.
How it would have been caught
Static analysis flags untrusted data flowing into a sink (innerHTML, unescaped template output); dynamic scanners (OWASP ZAP, Burp) inject probe payloads and observe whether they render as live script. A reproduction stores a script payload, loads the page as a second user, and confirms the script executes (for example, exfiltrating a cookie to a canary endpoint).
How to prevent it
- Encode output for its exact context (HTML, attribute, JS, URL); prefer frameworks that auto-escape and avoid
dangerouslySetInnerHTML/innerHTMLwith untrusted data. - Deploy a strict Content Security Policy so injected inline script cannot run even if it lands.
- Mark session cookies
HttpOnlyandSecureso a successful XSS cannot read them directly.
The Breachwire test (red → green)
Store a script payload, view the page as a different user, and confirm it executes and exfiltrates a session token — the RED control. Apply context-aware output encoding and a CSP, then confirm the same payload renders as inert text and the browser blocks any inline execution.