Breachwire.riscent

Breach report

Stored XSS to account takeover: the web's most common bug class

Web Application BreachesHigh to Critical (context-dependent)2024-01
The bottom lineCross-site scripting is the single most common vulnerability class in bug bounty and the #1 entry on the CWE Top 25; injected script running in a victim's browser can steal session tokens and drive full account takeover.
Category
Web Application Breaches
Type
Vulnerability class · #1 CWE / top bug-bounty finding
Date
2024-01
Severity
High to Critical (context-dependent)
OWASP
Web A05 Injection
CWE / CVE
CWE-79

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/innerHTML with untrusted data.
  • Deploy a strict Content Security Policy so injected inline script cannot run even if it lands.
  • Mark session cookies HttpOnly and Secure so 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.