skills/attack-surface-xss/SKILL.md
Reconnaissance skill for XSS attack surface — analyzes headers, frameworks, JS libraries, and DOM patterns at a URL to map what makes XSS possible or harder. For ethical hackers preparing for XSS testing.
npx skillsauth add igbuend/grimbard attack-surface-xssInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Map the XSS attack surface of a target URL. Analyze security headers, client-side frameworks, JavaScript patterns, and DOM structure to identify what makes XSS possible, easier, or harder.
This skill does NOT inject payloads or test for XSS. It performs passive observation only (HTTP requests + source analysis). For active XSS testing, use /xss-finder.
Target: $ARGUMENTS (URL to analyze)
/xss-finder — understand what defenses exist| Capability | Description | |------------|-------------| | Header Assessment | CSP, X-Content-Type-Options, cookie flags, charset | | Framework Detection | React, Angular, Vue, jQuery + version extraction | | Vulnerable Library Detection | Known CVEs per detected library version | | DOM XSS Source/Sink Mapping | innerHTML, eval, location.hash, postMessage | | Input Vector Enumeration | Forms, hidden fields, URL parameter reflection | | Attack Priority Ranking | Ordered list of where to focus XSS testing |
Retrieve response headers and page content from $ARGUMENTS:
# Response headers (follow redirects)
curl -sI -L "$URL"
# Full page body (HTML + inline JS)
curl -sL "$URL" -o /tmp/xss-recon-body.html
Use WebFetch as fallback for JavaScript-rendered content (SPAs that return minimal HTML).
Extract script references:
<script> tags — capture both inline content and external src URLsRecord metadata:
Check each header and rate its XSS impact:
| Header | Check | XSS Impact |
|--------|-------|------------|
| Content-Security-Policy | Present? unsafe-inline? Wildcards? Bypass CDNs? | Primary XSS defense |
| Content-Security-Policy-Report-Only | Non-enforcing — intel only | Shows intended policy |
| X-Content-Type-Options | nosniff present? | Blocks MIME-confusion script execution |
| X-XSS-Protection | Deprecated; 0 = deliberately disabled | Legacy posture indicator |
| Referrer-Policy | Data leak control | Referer-based injection intel |
| Permissions-Policy | Feature restrictions | Limits attack surface |
| Content-Type | Charset specified? | Missing charset enables UTF-7/ISO-2022-JP XSS |
| Set-Cookie | HttpOnly, Secure, SameSite flags | Cookie theft feasibility |
CSP quick assessment (inline):
unsafe-inline in script-src → inline script injection works directlyunsafe-eval → eval-based payloads viable* or data: in script-src → script loading from any originstrict-dynamic present → script gadget focus, not direct injectionFor deep CSP analysis, recommend running /content-security-policy $URL.
Cookie assessment:
HttpOnly → document.cookie exfiltration worksSecure → network MITM can steal cookiesSameSite → CSRF + XSS chaining viableDetect client-side stack from page source, script content, and global objects.
Frameworks — detection signatures:
| Framework | Detection Patterns |
|-----------|--------------------|
| React | data-reactroot, _reactRootContainer, __REACT_DEVTOOLS, react.production.min.js |
| Angular | ng-app, ng-version attribute, angular.js/angular.min.js in script src |
| Vue | data-v- attributes, __VUE__, vue.js/vue.min.js in script src |
| jQuery | jquery.min.js in script src, jQuery or $ assignment in inline scripts |
| Next.js | __NEXT_DATA__ script tag, _next/static paths |
| Nuxt | __NUXT__ global, _nuxt/ paths |
| Svelte | svelte in script paths, __svelte |
| Ember | ember.js in script src, data-ember- attributes |
| Backbone | backbone.js in script src |
Security libraries — detect sanitizers:
| Library | Detection | Notes |
|---------|-----------|-------|
| DOMPurify | dompurify in script src/content, DOMPurify.sanitize calls | Check version — mXSS bypasses per version |
| sanitize-html | sanitize-html in script paths | Server-side usually, may appear in bundles |
| Helmet.js | Infer from header patterns (X-DNS-Prefetch-Control, X-Content-Type-Options set together) | Server-side only |
| Trusted Types | require-trusted-types-for in CSP, trustedTypes API usage | Browser-enforced sink protection |
Vulnerable library detection — extract versions from filenames and CDN URLs:
| Library | Vulnerable Versions | XSS-Relevant Issue |
|---------|--------------------|--------------------|
| jQuery < 3.5.0 | jquery-3.2.1.min.js, CDN path version | $.htmlPrefilter XSS (CVE-2020-11022, CVE-2020-11023) |
| Angular < 1.6.x | angular.js/1.5.8/ in CDN URL | Template sandbox escape: {{$on.constructor('alert(1)')()}} |
| DOMPurify < 2.4.0 | dompurify/2.3.x/ in CDN URL | mXSS via SVG+style namespace confusion |
| lodash < 4.17.21 | lodash/4.17.x/ in CDN URL | Prototype pollution gadgets → XSS chain |
| Handlebars < 4.7.7 | handlebars/4.7.x/ in CDN URL | Prototype pollution → template injection |
| Moment.js | Any version | ReDoS, often bundled with vulnerable deps |
For each detected library: report version, known XSS-relevant CVEs, and specific exploitation notes.
Analyze inline scripts and fetched JS files for dangerous patterns.
DOM XSS Sinks (code that writes to DOM unsafely):
| Sink | Pattern | Risk Level |
|------|---------|------------|
| innerHTML | el.innerHTML = ... | High — direct HTML injection |
| outerHTML | el.outerHTML = ... | High — replaces entire element |
| document.write() | document.write(...) | High — writes to document stream |
| document.writeln() | document.writeln(...) | High — same as write with newline |
| insertAdjacentHTML() | el.insertAdjacentHTML(...) | High — injects HTML at position |
| eval() | eval(...) | Critical — arbitrary code execution |
| Function() | new Function(...) | Critical — creates function from string |
| setTimeout(string) | setTimeout("...", ...) | High — eval equivalent |
| setInterval(string) | setInterval("...", ...) | High — eval equivalent |
| $.html() | $(sel).html(...) | High — jQuery innerHTML wrapper |
| $(user_input) | $(location.hash) | Critical — jQuery selector injection |
| v-html | v-html="..." directive | High — Vue raw HTML binding |
| dangerouslySetInnerHTML | dangerouslySetInnerHTML={{...}} | High — React raw HTML |
| location.href = | location.href = ... | Medium — open redirect → XSS chain |
| location.assign() | location.assign(...) | Medium — redirect sink |
| location.replace() | location.replace(...) | Medium — redirect sink |
| window.open() | window.open(...) | Medium — navigation sink |
| navigation.navigate() | navigation.navigate(...) | Medium — Chrome navigation API |
| Dynamic import() | import(...) | High — module loading sink |
DOM XSS Sources (where attacker input enters):
| Source | Pattern | Notes |
|--------|---------|-------|
| location.hash | location.hash, window.location.hash | Fragment — not sent to server |
| location.search | location.search, URLSearchParams | Query string |
| location.href | location.href (read) | Full URL including fragment |
| document.referrer | document.referrer | Attacker-controlled via link |
| window.name | window.name | Persists across navigations |
| document.cookie | document.cookie (read) | If attacker can set cookies |
| postMessage | addEventListener('message', ...) | Check origin validation |
| localStorage | localStorage.getItem(...) | Persistent, attacker-settable |
| sessionStorage | sessionStorage.getItem(...) | Session-scoped |
| URL() constructor | new URL(...), url.searchParams | Parameter parsing |
Source-to-sink tracing (static approximation):
For each detected source, trace whether it flows into a sink without sanitization. Flag direct connections (e.g., el.innerHTML = location.hash). Note: full taint analysis requires browser DevTools or dynamic instrumentation — this is a best-effort static scan.
Dangerous constructs:
| Construct | Pattern | XSS Relevance |
|-----------|---------|---------------|
| Global variable declarations | var config = ... on window | DOM clobbering targets (see dom-clobbering anti-pattern) |
| Prototype pollution gadgets | Object.assign, $.extend, _.merge with user input | Gadget chain → XSS |
| JSONP endpoints | callback= parameter in script src | Arbitrary JS execution via callback |
| postMessage without origin check | addEventListener('message', fn) without event.origin validation | Any origin can inject data |
| Template literal injection | `...${userInput}...` in dangerous contexts | String interpolation into sinks |
| with statements | with(obj) { ... } | Scope confusion, clobbering |
| Relative script loading | <script src="./app.js"> | RPO vulnerability — path confusion |
Analyze page structure for XSS-relevant features.
Input vectors:
<input>, <textarea>, <select> elements (visible + hidden)name, type, id, maxlength, pattern attributesaction URLs and method (GET/POST)URL parameter reflection test: For each URL parameter in $ARGUMENTS, check if value appears in response body. If reflected, note the reflection context (HTML body, attribute, script, comment).
Meta tags:
| Tag | Check | XSS Impact |
|-----|-------|------------|
| <meta charset> | Missing? | Enables charset-based XSS (ISO-2022-JP, UTF-7) |
| <meta http-equiv="Content-Security-Policy"> | Present? | Meta CSP — limited (no frame-ancestors, no report-uri) |
| <meta http-equiv="refresh"> | User-controllable URL? | Redirect vector |
Embedding elements:
<iframe> — sandboxed? Is src user-controllable?<object>, <embed> — plugin execution vectors<svg> — enables advanced XSS vectors (onbegin, SMIL <animate>)<math> — MathML namespace confusion for mXSS (reference mutation-xss anti-pattern)Inline event handlers:
Count existing inline event handlers (onclick, onerror, onload, etc.) in page source. High count indicates the framework does not prohibit inline handlers — weak or absent CSP likely.
Third-party embeds:
gtm.js) — tag injection surfaceGenerate a structured report organized for ethical hacker workflow:
# XSS Attack Surface Report
**Target:** {URL}
**Date:** {date}
**Overall XSS Resistance:** {Strong | Moderate | Weak | Minimal}
## Executive Summary
{2-3 sentences: key findings, biggest weaknesses, recommended testing focus}
## Security Headers
| Header | Value | XSS Impact | Assessment |
|--------|-------|------------|------------|
| CSP | {value or MISSING} | {impact} | {Strong/Weak/Missing} |
| X-Content-Type-Options | {value or MISSING} | {impact} | {OK/Missing} |
| Set-Cookie | {flags or MISSING} | {impact} | {assessment} |
| ... | | | |
**Hacker Notes:** {Specific header weaknesses — e.g. "CSP has unsafe-inline, inline
script injection works directly" or "No HttpOnly on session cookie, document.cookie
exfiltration viable"}
## Technology Stack
| Component | Version | XSS Relevance |
|-----------|---------|---------------|
| {library} | {version} | {specific CVE or known bypass} |
**Hacker Notes:** {Which libraries have known bypasses, specific payloads to try}
## Dangerous JavaScript Patterns
### DOM XSS Sinks Found
| Sink | Location | Source Connected | Risk |
|------|----------|-----------------|------|
| innerHTML | inline script line 42 | location.hash | High — direct DOM XSS |
| $.html() | app.js:156 | AJAX response | Medium — depends on server sanitization |
### DOM XSS Sources Found
| Source | Handler | Origin Check | Risk |
|--------|---------|--------------|------|
| postMessage | addEventListener line 88 | No | High — any origin can inject |
| location.hash | hashchange handler | N/A | Medium — client-only input |
### Dangerous Constructs
{DOM clobbering targets, prototype pollution gadgets, JSONP endpoints, relative paths}
**Hacker Notes:** {Specific source→sink chains to investigate, bypass techniques from
xss-finder 5-Rotor methodology}
## Input Vectors
| Input | Type | Reflected | Hidden | Notes |
|-------|------|-----------|--------|-------|
| q | text | Yes | No | Search param reflected in <h1> |
| token | hidden | No | Yes | Likely unsanitized — test stored XSS |
**Hacker Notes:** {Which inputs to fuzz first, client-side restrictions to bypass}
## Best Practices Assessment
| Practice | Status | Hacker Implication |
|----------|--------|--------------------|
| CSP with nonce/hash | {Present/Missing} | {implication for inline injection} |
| HttpOnly cookies | {Present/Missing} | {cookie theft feasibility} |
| DOMPurify/sanitizer | {Present/Missing (version)} | {mXSS bypass options} |
| Trusted Types | {Present/Missing} | {sink restriction status} |
| Subresource Integrity | {Present/Missing} | {CDN MITM feasibility} |
| Meta charset | {Present/Missing} | {charset-based XSS feasibility} |
## Attack Vectors Summary
### High Priority (Test First)
1. {Most promising vector with technique reference}
2. {Second most promising}
3. {Third}
### Medium Priority
1. {Vector with conditional exploitability}
2. ...
### Low Priority (Hardened)
1. {Defended vector — explain what makes it hard}
2. ...
## Recommended Next Steps
1. Run `/xss-finder $URL` for automated payload testing on identified vectors
2. Run `/content-security-policy $URL` for deep CSP analysis
3. {Specific manual tests based on findings — e.g. "Test postMessage handler at
line 88 with origin-less messages", "Fuzz hidden field 'token' for stored XSS"}
Overall XSS Resistance rating:
Each finding must reference specific exploitation techniques. Link to xss-finder 5-Rotor methodology where relevant (context detection, bypass cascades, encoding techniques).
http:// or https://)curl -sI -L; fetch body with curl -sLBefore finalizing:
/xss-finder and /content-security-policySingle URL reconnaissance:
/xss-recon https://example.com/search?q=test
Application homepage:
/xss-surface https://app.example.com
Pre-engagement scoping:
/xss-attack-surface https://target.com/login
/content-security-policy $URL/xss-finder $URLdevelopment
Security anti-pattern for Cross-Site Scripting vulnerabilities (CWE-79). Use when generating or reviewing code that renders HTML, handles user input in web pages, uses innerHTML/document.write, or builds dynamic web content. Covers Reflected, Stored, and DOM-based XSS. AI code has 86% XSS failure rate.
development
Security anti-pattern for XPath injection vulnerabilities (CWE-643). Use when generating or reviewing code that queries XML documents, constructs XPath expressions, or handles user input in XML operations. Detects unescaped quotes and special characters in XPath queries.
development
Security anti-pattern for weak password hashing (CWE-327, CWE-759). Use when generating or reviewing code that stores or verifies user passwords. Detects use of MD5, SHA1, SHA256 without salt, or missing password hashing entirely. Recommends bcrypt, Argon2, or scrypt.
development
Security anti-pattern for weak encryption (CWE-326, CWE-327). Use when generating or reviewing code that encrypts data, handles encryption keys, or uses cryptographic modes. Detects DES, ECB mode, static IVs, and custom crypto implementations.