VYPR
Moderate severityNVD Advisory· Published Jun 4, 2018· Updated Sep 17, 2024

CVE-2017-16016

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.

PackageAffected versionsPatched versions
sanitize-htmlnpm
< 1.11.41.11.4

Affected products

2

Patches

1
5d205a1005ba

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.

https://github.com/punkave/sanitize-htmlTom BoutellMar 28, 2016via ghsa
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() {
           }), '&quot;normal text&quot;<style>body { background-image: url("image.test"); }</style>'
         );
       });
    +  it('should not unescape escapes found inside script tags', function() {
    +    assert.equal(
    +      sanitizeHtml('<script>alert("&quot;This is cool but just ironically so I quoted it&quot;")</script>',
    +        {
    +          allowedTags: [ 'script' ]
    +        }
    +      ),
    +      '<script>alert("&quot;This is cool but just ironically so I quoted it&quot;")</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>&lt;/textarea&gt;&lt;svg/onload=prompt`xs`&gt;</textarea>!',
    +        { allowedTags: [ 'textarea' ] }
    +      ), '!<textarea>&lt;/textarea&gt;&lt;svg/onload=prompt`xs`&gt;</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

News mentions

0

No linked articles in our index yet.