dom-vulnerability-static-analysis · git:20260528.f3e4348 · 2026-05-28 · sha256 318b8ba9b71002a0

dom-vulnerability-static-analysis git:20260528.f3e4348A

Immutable. This exact content is served forever at /api/v1/blob/318b8ba9b71002a0.

---
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
grep -rn 'innerHTML\|outerHTML\|document\.write\|insertAdjacentHTML\|\.html(' \
  --include="*.js" --include="*.jsx" --include="*.ts" --include="*.tsx" src/

# Find eval-family sinks
grep -rn 'eval(\|new Function(\|setTimeout([^,]*["\x27]\|setInterval([^,]*["\x27]' \
  --include="*.js" --include="*.ts" src/

# Find URL assignment sinks
grep -rn 'location\.\(href\|assign\|replace\)\s*=\|window\.open(' \
  --include="*.js" --include="*.ts" src/

# Find attacker-controlled sources
grep -rn 'location\.\(hash\|search\|href\)\|document\.URL\|document\.referrer\|window\.name\|postMessage' \
  --include="*.js" --include="*.ts" src/

# Framework-specific sinks
grep -rn 'dangerouslySetInnerHTML\|v-html\|ng-bind-html\|\[innerHTML\]\|hx-get\|hx-post' \
  --include="*.js" --include="*.tsx" --include="*.html" --include="*.vue" src/

# AngularJS CSTI: user input bound to scope then evaluated in {{ }} templates
# Payload: {{constructor.constructor('alert(1)')()}} (sandbox escape for AngularJS 1.x)
grep -rn 'ng-app\|ng-bind\|\$scope\.\|ng-model\|ng-bind-html' \
  --include="*.html" --include="*.js" src/

# Prototype pollution sources: Object.assign/spread with user-controlled input
grep -rn 'Object\.assign\|\.\.\..*param\|\.\.\..*query\|merge(' \
  --include="*.js" --include="*.ts" src/
```

## 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?
grep -rn "content\s*=" --include="*.js" src/ | grep -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
grep -rn "DOMPurify\|dompurify\|sanitize(" --include="*.js" --include="*.ts" src/

# Find custom sanitizers
grep -rn "function.*sanitiz\|function.*escape\|function.*clean\|function.*filter" \
  --include="*.js" --include="*.ts" src/
```

For custom sanitizers: apply the `custom-sanitizer-audit` skill (Five-Point Checklist).
For DOMPurify: check version and config — see `dompurify-mxss-bypass` skill.

## 4. AST-based analysis (optional)

For large codebases, use tooling:
- **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. Cross-validate findings

Before reporting, reduce false positives by cross-referencing:
- Compare grep-based sink hits (steps 1-2) against AST taint-tracking results (step 4) — a finding confirmed by both methods is high-confidence
- For grep-only hits: manually verify the data flow in context (minified code aliasing can produce false matches)
- For AST-only hits: confirm the sink pattern wasn't missed by grep regex limitations
- Discard any finding where the source is provably non-attacker-controlled after contextual review

## 6. 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

## 7. Library-specific XSS gadgets

See `GADGETS.md` for jQuery `.text()` re-decoding, moment.js format injection, and `javascript:` URI hostname bypass patterns.

## Chain With
- `dom-vulnerability-detection` (dynamic analysis), `csp-bypass` (CSP blocks), `dompurify-mxss-bypass` (DOMPurify), `aem-sling-exploitation` (AEM-specific XSS gadgets)