Score context-aware output encoding across HTML, attribute, JavaScript, URL and CSS sinks, weighted by how dangerous each context is.
One escaping function cannot serve five contexts: HTML entity encoding is correct in a body, useless inside a script block and wrong for a URL, where the scheme must also be checked. The JavaScript context is weighted highest because it needs the strictest encoding and is the context developers most often get wrong. Encoding is where XSS is actually prevented or not, and the failures cluster in the contexts that framework auto-escaping does not cover — inline script, event handlers and href attributes.
Output Encoding
encoding score = 0.30 × JavaScript coverage + 0.20 × HTML body + 0.20 × attribute + 0.15 × URL + 0.15 × CSS, each the share of sinks in that context that are correctly encoded.
encoding score = 0.30 × JavaScript coverage + 0.20 × HTML body + 0.20 × attribute + 0.15 × URL + 0.15 × CSS, each the share of sinks in that context that are correctly encoded. One escaping function cannot serve five contexts: HTML entity encoding is correct in a body, useless inside a script block and wrong for a URL, where the scheme must also be checked. The JavaScript context is weighted highest because it needs the strictest encoding and is the context developers most often get wrong.
Encoding is where XSS is actually prevented or not, and the failures cluster in the contexts that framework auto-escaping does not cover — inline script, event handlers and href attributes.
This calculator takes 10 inputs: HTML body sinks, HTML body sinks correctly encoded, HTML attribute sinks, Attribute sinks correctly encoded, JavaScript context sinks, JavaScript sinks correctly encoded, URL and href sinks, URL sinks correctly encoded and scheme-checked, CSS or style sinks, CSS sinks correctly encoded. The pre-filled defaults are a realistic starting point — replace them with figures from your own environment for a result you can act on.
Serialise it as JSON and read it from the DOM rather than interpolating into JavaScript source. Emit it in a <script type="application/json"> block with HTML encoding, then JSON.parse the text content. That removes the need for JavaScript string escaping entirely, which is the part that goes wrong.