Template Literals
debt(d5/e3/b3/t7)
Closest to 'specialist tool catches it' (d5). ESLint and Semgrep can detect the pattern of innerHTML with template literals containing variables, but this requires rule configuration and doesn't catch all XSS vectors—runtime context matters (was the variable sanitised upstream?). The detection is not automatic without explicit rules enabled.
Closest to 'simple parameterised fix' (e3). The quick_fix is clear: replace innerHTML with textContent or switch to a tagged template library. This is typically a single-call or single-pattern swap within one component, though widespread innerHTML usage may require multiple edits in one file.
Closest to 'localised tax' (b3). Template literals are localised to string-building contexts; the choice doesn't reshape the entire codebase. However, if a team adopts unsafe innerHTML + template literal patterns widely, it creates scattered XSS risk. The burden is moderate because the unsafe pattern is easy to repeat but contained to rendering logic.
Closest to 'serious trap' (t7). The misconception explicitly states that template literals *feel* safe (readable, modern syntax) but are not inherently safe when combined with innerHTML—contradicting how similar string operations work in safer contexts (textContent, DOM methods). A developer familiar with template literals from safe contexts (console.log, assignments) will assume the same safety applies to DOM insertion, which is wrong.
Also Known As
TL;DR
Explanation
Template literals use backticks and support multi-line strings and ${expression} interpolation. Tagged templates allow custom processing: html`<div>${userInput}</div>` can auto-escape. Nesting: `${condition ? `<span>${val}</span>` : ''}`. PHP parallel: double-quoted "Hello $name" and heredoc. Key difference: PHP interpolates at string creation time; JS template literals evaluate the expression — you can embed any JS expression, not just variables.
Common Misconception
Why It Matters
Common Mistakes
- Using innerHTML with template literal containing user data — XSS
- Nesting backtick strings without proper escaping
- Forgetting tagged templates for HTML generation
Code Examples
// XSS — user input in template literal via innerHTML:
el.innerHTML = `<li class="item">${user.bio}</li>`;
// Safe with textContent:
const li = document.createElement('li');
li.className = 'item';
li.textContent = user.bio; // safe
// Tagged template for automatic escaping:
const html = (strings, ...values) =>
strings.reduce((r, s, i) =>
r + s + (values[i] != null
? String(values[i]).replace(/&/g,'&').replace(/</g,'<')
: ''), '');
el.innerHTML = html`<li class="item">${user.bio}</li>`;