CVE-2017-16016
Description
Sanitize-html is a library for scrubbing html input of malicious values. Versions 1.11.1 and below are vulnerable to cross site scripting (XSS) in certain scenarios: If allowed at least one nonTextTags, the result is a potential XSS vulnerability.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Sanitize-html <=1.11.1 allows XSS when nonTextTags are allowed, due to improper escaping of decoded entities.
Vulnerability
Sanitize-html versions 1.11.1 and below [1] are vulnerable to cross-site scripting (XSS) when at least one nonTextTags (e.g., textarea) is allowed [4]. The library incorrectly handles HTML-encoded content inside allowed non-text tags, decoding entities too early and allowing injection of arbitrary HTML [2][4].
Exploitation
An attacker can craft input with a textarea tag containing HTML-encoded malicious payload. When sanitize-html processes the input, the entity decoding happens before the tag content is escaped, allowing the payload to be rendered as HTML [4]. No authentication is required; the attack is triggered when a user views the sanitized output.
Impact
Successful exploitation leads to arbitrary JavaScript execution in the context of the victim's browser, enabling cookie theft, page defacement, or redirection to malicious sites [3].
Mitigation
The vulnerability is fixed in sanitize-html version 1.11.2 [2]. Users should upgrade to 1.11.2 or later. The fix adds textarea to the default nonTextTags list and escapes content appropriately [2]. No workarounds are available for earlier versions.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
sanitize-htmlnpm | < 1.11.4 | 1.11.4 |
Affected products
2- HackerOne/sanitize-html node modulev5Range: <=1.11.1
Patches
15d205a1005baFixed XSS attack vector via `textarea` tags (when explicitly allowed). Decided that `script` (obviously) and `style` (due to its own XSS vectors) cannot realistically be afforded any XSS protection if allowed, unless we add a full CSS parser. Thanks again to Andrew Krasichkov.
3 files changed · +28 −3
index.js+5 −1 modified@@ -205,7 +205,11 @@ function sanitizeHtml(html, options, _recursing) { text = lastFrame.innerText !== undefined ? lastFrame.innerText : text; } - if (nonTextTagsArray.indexOf(tag) !== -1) { + if ((tag === 'script') || (tag === 'style')) { + // htmlparser2 gives us these as-is. Escaping them ruins the content. Allowing + // script tags is, by definition, game over for XSS protection, so if that's + // your concern, don't allow them. The same is essentially true for style tags + // which have their own collection of XSS vectors. result += text; } else { var escaped = escapeHtml(text);
README.md+5 −1 modified@@ -8,7 +8,7 @@ `sanitize-html` allows you to specify the tags you want to permit, and the permitted attributes for each of those tags. -If a tag is not permitted, the contents of the tag are still kept, except for script and style tags. +If a tag is not permitted, the contents of the tag are still kept, except for `script`, `style` and `textarea` tags. The syntax of poorly closed `p` and `img` elements is cleaned up. @@ -295,10 +295,14 @@ nonTextTags: [ 'style', 'script', 'textarea', 'noscript' ] Note that if you use this option you are responsible for stating the entire list. This gives you the power to retain the content of `textarea`, if you want to. +The content still gets escaped properly, with the exception of the `script` and `style` tags. *Allowing either `script` or `style` leaves you open to XSS attacks. Don't do that* unless you have good reason to trust their origin. + ## Changelog 1.11.4: fixed crash when `__proto__` is a tag name. Now using a safe check for the existence of properties in all cases. Thanks to Andrew Krasichkov. +Fixed XSS attack vector via `textarea` tags (when explicitly allowed). Decided that `script` (obviously) and `style` (due to its own XSS vectors) cannot realistically be afforded any XSS protection if allowed, unless we add a full CSS parser. Thanks again to Andrew Krasichkov. + 1.11.3: bumped `htmlparser2` version to address crashing bug in older version. Thanks to e-jigsaw. 1.11.2: fixed README typo that interfered with readability due to markdown issues. No code changes. Thanks to Mikael Korpela. Also improved code block highlighting in README. Thanks to Alex Siman.
test/test.js+18 −1 modified@@ -433,7 +433,7 @@ describe('sanitizeHtml', function() { }), '<a data-b.c="#test">click me</a>' ); }); - it('should not escape inner content from non-text tags (when allowed)', function() { + it('should not escape inner content of script and style tags (when allowed)', function() { assert.equal( sanitizeHtml('<div>"normal text"</div><script>"this is code"</script>', { allowedTags: [ 'script' ] @@ -445,6 +445,16 @@ describe('sanitizeHtml', function() { }), '"normal text"<style>body { background-image: url("image.test"); }</style>' ); }); + it('should not unescape escapes found inside script tags', function() { + assert.equal( + sanitizeHtml('<script>alert(""This is cool but just ironically so I quoted it"")</script>', + { + allowedTags: [ 'script' ] + } + ), + '<script>alert(""This is cool but just ironically so I quoted it"")</script>' + ) + }); it('should process text nodes with provided function', function() { assert.equal( sanitizeHtml('"normal text this should be removed"', { @@ -478,4 +488,11 @@ describe('sanitizeHtml', function() { sanitizeHtml("!<__proto__>!"), "!!"); }); + it('should correctly maintain escaping when allowing a nonTextTags tag other than script or style', function() { + assert.equal( + sanitizeHtml('!<textarea></textarea><svg/onload=prompt`xs`></textarea>!', + { allowedTags: [ 'textarea' ] } + ), '!<textarea></textarea><svg/onload=prompt`xs`></textarea>!' + ); + }); });
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-xc6g-ggrc-qq4rghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-16016ghsaADVISORY
- github.com/punkave/sanitize-html/commit/5d205a1005ba0df80e21d8c64a15bb3accdb2403ghsax_refsource_MISCWEB
- github.com/punkave/sanitize-html/commit/5d205a1005ba0df80e21d8c64a15bb3accdb2403)))ghsaWEB
- github.com/punkave/sanitize-html/issues/100ghsax_refsource_MISCWEB
- nodesecurity.io/advisories/154mitrex_refsource_MISC
- npmjs.com/package/sanitize-htmlghsaWEB
- www.npmjs.com/advisories/154ghsaWEB
News mentions
0No linked articles in our index yet.