
Xss Browser Confirm
Turn a suspected Cross-Site Scripting reflection or DOM sink into proof of JavaScript...
Install
npx skills add vigolium/vigolium --skill xss-browser-confirm -g -a claude-code -y- Repository
- vigolium/vigolium1.1k
- Category
- Writing
- Updated
- 10d ago
- License
- MIT
- Context cost
- Mediumabout 1,855 tokens
- Runs scripts
- No, instructions only
What it does
Turn a suspected Cross-Site Scripting reflection or DOM sink into proof of JavaScript execution by firing a uniquely-tagged dialog in a real headless browser via the browser_probe tool, not by string-matching the response. Covers reflected, stored, and DOM-based XSS, context-aware payload crafting (HTML body, attribute, JS string, URL/href, DOM sink), light WAF/encoding evasion when a payload reflects but doesn't execute, and persisting a finding sized by real impact. Use when a parameter's value appears in the response, when a DOM sink (innerHTML, document.write, eval, location) consumes input, when CWE-79 was flagged, or when a scanner saw reflection but couldn't confirm execution.
XSS → Browser-Confirmed Execution
You suspect XSS somewhere. Reflection is a hint, not proof. Your job is to
make JavaScript actually run in a real browser and capture the proof, then persist a finding with the exact URL that executed. browser_probe
loads a URL in headless Chrome and reports any alert/confirm/prompt
dialog that fires, even when nothing reflects visibly in the HTML. That
dialog is your oracle.
When this skill applies
- A URL/body/header param value appears in the response body or a header.
- A scanner/audit flagged CWE-79, "reflected XSS", "DOM XSS", or "reflection observed, execution unconfirmed".
- The page's JS feeds input into a sink:
innerHTML,outerHTML,document.write,eval,setTimeout(string),location/href,$(...).html(),dangerouslySetInnerHTML.
If you only have "fuzz everything", anchor on a record first
(query_records for reflected params / search endpoints, then
inspect_record). Don't probe blind.
The canary discipline
Use one unique canary per probe so a dialog can't be a coincidence or a
leftover from another page. Make it specific and greppable, e.g.
alert('xss-9f3a2c'). After browser_probe, the proof is
dialog_fired == true and the dialog message equals your canary. A
dialog with a different message is the app's own JS, not your finding.
remember the canary + target as xss-target so it survives context churn.
Workflow
1. Anchor and find the reflection / sink
inspect_record the candidate. Find where the input lands:
- In the response body → reflected; note the surrounding bytes.
- Consumed by client JS with no server reflection → DOM-based; read the
JS to find the sink and the source (
location.hash,location.search,document.referrer,postMessage). - Persisted then rendered on another page (profile, comment, admin panel) → stored; note the injection request and the rendering URL.
