No dynamic script injection with user-controlled content
Why it matters
Dynamic DOM injection — document.write(), innerHTML assignments with external content, and dynamically created <script> elements with user-controlled sources — creates XSS vulnerabilities that CSP cannot fully mitigate. An attacker who controls any input to these patterns achieves script execution in the user's browser context: session token theft, credential harvesting, or full account takeover. CWE-79 (XSS) and CWE-83 (Script in HTML Attribute) both apply directly. OWASP A03 (Injection) lists DOM-based XSS as a primary injection vector. These patterns persist in codebases long after their introduction because they appear to work correctly during normal operation — failures only surface under adversarial input.
Severity rationale
Critical because `innerHTML` with external content, `document.write()`, and dynamic script injection are direct XSS vectors that enable arbitrary script execution regardless of CSP configuration, since CSP cannot prevent patterns already executing in trusted script context.
Remediation
Replace DOM injection patterns with safe equivalents. Text content should use textContent; structured content should use the DOM API or framework rendering.
// DANGEROUS: XSS vector
element.innerHTML = apiResponse.html
document.write('<script src=' + userInput + '></script>')
// SAFE: text only
element.textContent = apiResponse.text
// SAFE: structured DOM construction
const p = document.createElement('p')
p.textContent = apiResponse.title
container.appendChild(p)
// SAFE: React auto-escapes
return <div>{apiResponse.content}</div>
// LAST RESORT: sanitized HTML (treat as tech debt)
import DOMPurify from 'dompurify'
element.innerHTML = DOMPurify.sanitize(apiResponse.html)
DOMPurify reduces risk but does not eliminate the injection pattern — flag every innerHTML assignment in code review regardless of sanitization.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Security Headers II Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-79
- cwe · CWE-83 — Improper Neutralization of Script in Attributes in a Web Page
- owasp:2021 · A03
- soc2:2017 · CC6.8 — Prevention and detection of unauthorized or malicious software
Taxons
History
- 2026-04-18·v1.0.0·Initial import from security-headers-ii·automated
- 2026-07-06·v1.0.1·Add SOC 2 TSC mapping (CC6.8) from the verified compliance crosswalk register (docs/compliance/).·by soc2-mapping-enrichment-ship-2