Explain the difference between output escaping (context-specific encoding) and sanitizing user input (allowlist filtering). Include when to use each, how they work, and why both matter for XSS prevention.
Frontend interview answer
Escaping vs Sanitizing: What's the Difference?
Interview quick answer
Interview focus
This JavaScript interview question tests whether you can explain Escaping vs sanitizing: what is the difference, connect it to production trade-offs, and handle common follow-up questions.
- Escaping vs sanitizing: what is the difference explanation without falling back to memorized definitions
- Security and Html reasoning, edge cases, and production failure modes
- How you would answer the most likely JavaScript interview follow-up
Use this JavaScript interview question to rehearse a quick answer, common mistake, follow-up, and production pitfall.
Full interview answer
Big idea
Escaping and sanitizing both reduce XSS risk, but they solve different problems. Escaping encodes characters so the browser treats user input as text in a specific output context. Sanitizing removes or rewrites dangerous parts of user-provided markup so some HTML can be allowed.
Aspect | Escaping | Sanitizing |
|---|---|---|
Primary goal | Encode special characters so they render as text | Allow some HTML while blocking dangerous tags/attrs |
Input expectation | Plain text | HTML-like input |
Context | Context-specific (HTML text, attributes, URLs, JS, CSS) | HTML context only |
Typical tooling | textContent, template auto-escaping, encoding helpers | DOMPurify, browser sanitizer APIs, server allowlists |
Failure mode | Wrong encoder for the context can still allow XSS | Weak allowlist can allow XSS or strip too much content |
Real-world scenario
A profile bio can be plain text (escape and render safely), but a blog editor might allow limited rich text (sanitize with an allowlist). Decide based on the product requirement, not convenience.
const userInput = '<img src=x onerror=alert(1) />';
// Escaping (text only)
bioEl.textContent = userInput;
// Sanitizing (allow some HTML)
bioEl.innerHTML = DOMPurify.sanitize(userInput, {
ALLOWED_TAGS: ['b', 'i', 'a'],
ALLOWED_ATTR: ['href', 'rel', 'target']
});
Context | Use | Example |
|---|---|---|
HTML text | textContent / template escaping | el.textContent = userText |
HTML attribute | Set attributes with encoded values | el.setAttribute('title', safeText) |
URL | Allowlist protocols + URL parsing | new URL(input, location.origin) |
JS string | Avoid inline JS; never concatenate user input | Prefer data attributes or JSON |
Common pitfalls
- Stripping tags with regex (easy to bypass).
- Sanitizing once and reusing the result in a different context.
- Double-escaping by encoding the same value twice.
- Storing only sanitized HTML and losing the original data.
Summary
Escape for the specific output context. Sanitize only when you must allow markup, and pair it with defense-in-depth like CSP and Trusted Types.
Use this as one explanation rep, then continue with the JavaScript interview questions cluster or a guided prep path.