git:20260529.8f6ea0e to git:20260730.db45319

39 added, 2 removed. Audit A to A.

---
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
```bash
# Find all dangerous sinks
rg 'innerHTML|outerHTML|document\.write|insertAdjacentHTML|\.html\(' \
--type js --type ts -n src/
# Find eval-family sinks
rg 'eval\(|new Function\(|setTimeout\([^,]*["\x27]|setInterval\([^,]*["\x27]' \
--type js --type ts -n src/
# Find URL assignment sinks
rg 'location\.(href|assign|replace)\s*=|window\.open\(' \
--type js --type ts -n src/
# Find attacker-controlled sources
rg 'location\.(hash|search|href)|document\.URL|document\.referrer|window\.name|postMessage' \
--type js --type ts -n src/
# Framework-specific sinks
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:
```bash
# Find the variable assigned to the sink, then trace its origin
# Example: el.innerHTML = content -- where does `content` come from?
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
```bash
# Find DOMPurify usage
rg "DOMPurify|dompurify|sanitize\(" --type js --type ts -n src/
# Find custom sanitizers (WARNING: verify implementation before trusting)
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
+ `rg` patterns are fragile for code constructs โ€” they miss variations in whitespace, nesting, and comments. Use AST-based tools for structural matching.
+
+ ### ast-grep (installed in runtime)
+
+ ast-grep uses tree-sitter for structural code matching. Patterns use real code syntax with `$VAR` wildcards โ€” far more accurate than regex for function calls, assignments, and nested expressions.
+
+ ```bash
+ # innerHTML / outerHTML sinks โ€” catches any receiver expression
+ ast-grep -p '$EL.innerHTML = $VAR' -l js src/
+ ast-grep -p '$EL.outerHTML = $VAR' -l js src/
+
+ # insertAdjacentHTML
+ ast-grep -p '$EL.insertAdjacentHTML($POS, $CONTENT)' -l js src/
+
+ # eval-family sinks
+ ast-grep -p 'eval($INPUT)' -l js src/
+ ast-grep -p 'new Function($BODY)' -l js src/
+
+ # URL assignment sinks
+ ast-grep -p 'location.href = $VAR' -l js src/
+ ast-grep -p 'location.assign($URL)' -l js src/
+ ast-grep -p 'window.open($TARGET)' -l js src/
+
+ # postMessage handlers (multi-line aware)
+ ast-grep -p 'window.addEventListener("message", $HANDLER)' -l js src/
+
+ # React dangerouslySetInnerHTML
+ ast-grep -p 'dangerouslySetInnerHTML={{$VAR}}' -l tsx src/
+
+ # jQuery .html() sink
+ ast-grep -p '$EL.html($CONTENT)' -l js src/
+ ```
+
+ Add `--json` to any command for structured output with file paths, line/column positions, and captured metavariable values. This is useful for programmatic triage or feeding results into jxscout custom analyzers.
+
+ ### Additional AST tools (if operator-installed)
+
+ - **Semgrep**: `semgrep --config p/javascript` for DOM XSS rules (includes taint tracking in Pro)
+ - **CodeQL**: `javascript/ql/src/Security/CWE-079` for data-flow taint analysis
- **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)