XSS: the context decides the encoding
Why a single escaping helper is not enough — HTML body, attribute, JavaScript and URL contexts each need different handling, with notes on remediation and verification.
The core mistake
Teams apply one escaping function everywhere and assume they are done. Escaping is only correct relative to the context the value lands in.
- HTML body — HTML entity encoding is sufficient.
- HTML attribute — must be quoted and entity encoded; unquoted attributes break out without needing angle brackets.
- JavaScript — do not interpolate into script at all; pass data through a JSON-encoded data attribute and read it.
- URL — validate the scheme against an allow-list;
javascript:anddata:survive naive encoding. - CSS — avoid user input in style contexts entirely.
Remediation
Escape by default at the template layer, make raw output an explicit and reviewable exception, sanitise rich text with a
maintained library rather than a regular expression, and add a Content Security Policy without unsafe-inline as
defence in depth rather than as the primary control.
Verification
Test each reflection point in its actual context, including attribute and URL sinks, confirm the payload is rendered as text rather than parsed, and check that the CSP blocks injected inline script if a sink is ever missed.