Detect postMessage handlers that trust unvalidated origins or write attacker-controlled data to dangerous DOM sinks.
From vuln-scoutnpx claudepluginhub allsmog/vuln-scout --plugin vuln-scoutThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
This skill covers detecting and exploiting Cross-Origin Messaging (postMessage) vulnerabilities that lead to DOM-based XSS.
postMessage is a browser API that allows cross-origin communication between windows/iframes. When message handlers don't validate event.origin, any website can send malicious data that may execute as XSS.
Why This Is Critical:
A handler that accepts messages from ANY origin and writes to DOM:
window.addEventListener("message", (event) => {
const data = event.data;
document.getElementById("output")[".inner" + "HTML"] = data.html; // XSS!
});
window.addEventListener("message", (event) => {
if (event.origin !== "https://trusted-domain.com") {
return; // Reject untrusted origins
}
document.getElementById("output").textContent = data.text; // Safe
});
# Find all postMessage event listeners
grep -rniE "addEventListener\s*\(\s*['\"]message['\"]" --include="*.js" --include="*.ts" --include="*.html"
# Find direct onmessage assignments
grep -rniE "\.onmessage\s*=" --include="*.js" --include="*.ts"
# Find handlers and check next 10 lines for origin check
grep -rniE "addEventListener\s*\(\s*['\"]message['\"]" --include="*.js" --include="*.ts" -A 10 | grep -v "origin"
# event.data to DOM write sinks
grep -rniE "event\.data.*(inner|outer)HTML" --include="*.js" --include="*.ts"
# event.data to location (open redirect)
grep -rniE "event\.data.*location|location.*event\.data" --include="*.js" --include="*.ts"
# event.data assigned to variable (trace further)
grep -rniE "=\s*event\.data" --include="*.js" --include="*.ts"
| Pattern | Risk | Detection |
|---|---|---|
| No origin check + DOM sink | Critical | Missing event.origin validation |
| Weak origin check (regex) | High | origin.includes() or origin.match() |
| Variable assignment then sink | High | const data = event.data then later to sink |
jQuery .html() method | Critical | $(elem).html(event.data) |
When combined with SSRF (bot visits attacker URL):
http://localhost:1337/This chain bypasses Chrome's Private Network Access restrictions.
const ALLOWED_ORIGINS = ["https://trusted.com"];
window.addEventListener("message", (event) => {
if (!ALLOWED_ORIGINS.includes(event.origin)) {
return; // Reject
}
// Process message safely...
});
textContent instead of HTML sinksX-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'