# Xss Browser Confirm

Turn a suspected Cross-Site Scripting reflection or DOM sink into proof of JavaScript...

- Repository: https://github.com/vigolium/vigolium (1141 stars)
- Category: Writing
- License: MIT
- Last updated: 2026-10-25
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add vigolium/vigolium --skill xss-browser-confirm -g -a claude-code -y`
Codex: `npx skills add vigolium/vigolium --skill xss-browser-confirm -g -a codex -y`
Cursor: `npx skills add vigolium/vigolium --skill xss-browser-confirm -g -a cursor -y`
Gemini CLI: `npx skills add vigolium/vigolium --skill xss-browser-confirm -g -a gemini-cli -y`

## Description

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.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# 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.

### 2. Classify the injection context

The rest: https://github.com/vigolium/vigolium/blob/HEAD/internal/resources/olium/skills/xss-browser-confirm/SKILL.md
