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.
Escaping vs Sanitizing: What's the Difference?
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.
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 the relevant interview-question hub first, then move into a concrete study plan before targeted company sets.