DOM Manipulation
debt(d5/e1/b3/t7)
Closest to 'specialist tool catches it' (d5), because the detection_hints list eslint and semgrep as the tools, and the code_pattern specifically targets innerHTML with user-supplied content without DOMPurify. ESLint rules for no-unsanitized or semgrep patterns can flag these, but they require configuration beyond default linting, placing this squarely at d5.
Closest to 'one-line patch or single-call swap' (e1), because the quick_fix explicitly states 'Use textContent not innerHTML for user-generated text; use createElement+appendChild for structured content' — in most cases this is a direct property swap at the call site, not a multi-file refactor.
Closest to 'localised tax' (b3), because applies_to is scoped to web contexts only, and the burden is felt in individual components where DOM manipulation is written rather than being cross-cutting or architectural. Future maintainers must remember safe patterns per-usage but the rest of the codebase is largely unaffected.
Closest to 'serious trap' (t7), because the misconception field explicitly describes a non-obvious, cross-boundary confusion: developers believe PHP-originated content is safe because it was sanitized server-side, but if user input was stored then rendered, XSS is still possible client-side. This contradicts the mental model that 'backend = trusted' and is a documented, commonly hit gotcha that contradicts how server-side sanitization is understood to work.
Also Known As
TL;DR
Explanation
querySelector('#id') and querySelectorAll('.class') are the modern API. createElement + appendChild for safe node creation. innerHTML is fast but XSS-vulnerable with user content — use textContent for text, createElement for structured content. dataset reads data-* attributes set by PHP. PHP renders HTML; JavaScript enhances it progressively. getElementById is slightly faster for id lookups but querySelector is more flexible.
Common Misconception
Why It Matters
Common Mistakes
- Using innerHTML with user-generated content — XSS risk
- Not checking if element exists before accessing properties
- document.write() — blocks parser and overwrites document
- Querying DOM before DOMContentLoaded fires
Code Examples
// XSS if username comes from user input via PHP:
document.querySelector('#greeting').innerHTML = 'Hello ' + username;
// Race condition — element may not exist yet:
const el = document.querySelector('#late-element').textContent;
// Safe text insertion:
document.querySelector('#greeting').textContent = 'Hello ' + username;
// Safe structured content:
const li = document.createElement('li');
li.textContent = item.name; // safe
li.dataset.id = item.id;
list.appendChild(li);
// Read PHP data-* attributes:
const userId = document.querySelector('[data-user-id]')?.dataset.userId;