| name | dom-vulnerability-static-analysis |
| description | Static code analysis for DOM-based vulnerabilities in client-side JavaScript -- source/sink enumeration via grep and AST tools, data flow tracing, sanitization assessment, and framework-specific sink detection. Use when performing pre-commit reviews, auditing large codebases without dynamic execution, or triaging minified code for XSS issues. |
Static analysis framework for DOM XSS -- no dynamic execution needed.
1. Enumerate sources and sinks
rg 'innerHTML|outerHTML|document\.write|insertAdjacentHTML|\.html\(' \
--type js --type ts -n src/
rg 'eval\(|new Function\(|setTimeout\([^,]*["\x27]|setInterval\([^,]*["\x27]' \
--type js --type ts -n src/
rg 'location\.(href|assign|replace)\s*=|window\.open\(' \
--type js --type ts -n src/
rg 'location\.(hash|search|href)|document\.URL|document\.referrer|window\.name|postMessage' \
--type js --type ts -n src/
rg 'dangerouslySetInnerHTML|v-html|ng-bind-html|\[innerHTML\]|hx-get|hx-post' \
--type js --type html -g "*.vue" -g "*.tsx" -n src/
Checkpoint: Record total sink count and source count. If sinks > 50, prioritize by category (eval-family first, then innerHTML, then URL assignment).
2. Trace data flow (source -> sink)
For each sink hit, trace backwards to determine if attacker input reaches it:
rg "content\s*=" --type js -n src/ | rg -i "location|param|query|hash|input|request"
Classify each finding:
- Direct flow: source -> sink with no sanitization = vulnerability
- Sanitized flow: source -> sanitizer -> sink = check sanitizer adequacy
- Static content: hardcoded string -> sink = not exploitable
3. Assess sanitization
rg "DOMPurify|dompurify|sanitize\(" --type js --type ts -n src/
rg "function.*(sanitiz|escape|clean|filter)" --type js --type ts -n src/
For custom sanitizers: apply the custom-sanitizer-audit skill (Five-Point Checklist).
For DOMPurify: check version and config -- see dompurify-mxss-bypass skill.
Checkpoint: For each custom sanitizer found, read the implementation. A function named escapeHTML that is NOT a standard library must be reviewed for bypass potential before marking flows through it as safe.
4. AST-based analysis (large codebases)
- Semgrep:
semgrep --config p/javascript for DOM XSS rules
- CodeQL:
javascript/ql/src/Security/CWE-079 for taint tracking
- ESLint:
no-unsanitized/property, no-unsanitized/method
5. Report findings
For each confirmed source-to-sink flow:
- File, line number, sink type
- Source of attacker input
- Sanitization present (yes/no, adequate/inadequate)
- Exploitability assessment
- Recommended fix
Chain With
dom-vulnerability-detection (dynamic analysis), csp-bypass (CSP blocks), custom-sanitizer-audit (homegrown sanitizer), dompurify-mxss-bypass (DOMPurify)