sanitize-html

Ecosystem: npm

Downloads: 57.61 Mln

Vulnerabilities from the last (months)
  • 1CriticalAffects 1 version
  • 1HighAffects 1 version
  • 0MediumAffects 0 versions
  • 14ModerateAffects 14 versions
  • 1LowAffects 1 version
Severity distribution (all time)
17vulnerabilities
  • Critical1 (5.9%)
  • High1 (5.9%)
  • Medium0 (0.0%)
  • Moderate14 (82.4%)
  • Low1 (5.9%)

Monthly breakdown

  • Critical
  • High
  • Medium
  • Moderate
  • Low
  • 4 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 3
    • Low: 1
  • 2 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 2
    • Low: 0
  • 1 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 1
    • Low: 0
  • 1 vulnerabilities
    • Critical: 1
    • High: 0
    • Medium: 0
    • Moderate: 0
    • Low: 0
  • 1 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 1
    • Low: 0
  • 1 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 1
    • Low: 0
  • 1 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 1
    • Low: 0
  • 1 vulnerabilities
    • Critical: 0
    • High: 1
    • Medium: 0
    • Moderate: 0
    • Low: 0
  • 2 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 2
    • Low: 0
  • 1 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 1
    • Low: 0
  • 2 vulnerabilities
    • Critical: 0
    • High: 0
    • Medium: 0
    • Moderate: 2
    • Low: 0

Vulnerabilities (17)

Known vulnerabilities affecting sanitize-html, based on data from OSV.

Vulnerabilities affecting sanitize-html
IDSeveritySummaryAffected versionsPublishedSource
GHSA-c9rx-x947-fp3hModerateApostropheCMS sanitize-html: unbounded recursion when re-sanitizing the fallback of a discarded iframe (stack overflow, nestingLimit not enforced)### Summary Since 2.18.0, when an `<iframe>` is not allowed and `disallowedTagsMode` is `'discard'` (the defaults), its raw-text content is re-sanitized by a recursive call to `sanitizeHtml(text, options)` (the change from #5564, fixing #5550). The recursion has no bound and starts each nested call with a fresh state. Two consequences, both absent from 2.17.7 and 2.17.4: 1. A few kilobytes of unclosed `<iframe>` tags throw `RangeError: Maximum call stack size exceeded` with the default options. Any application that sanitizes untrusted HTML with 2.18.0 can be made to throw on a small cr
  • >= 2.18.0, < 2.18.1
GitHub (opens in a new tab)
GHSA-374f-7chj-9948LowApostropheCMS sanitize-html: SMIL animation namespace-prefix bypass allows javascript: URI injection (XSS)## Summary sanitize-html 2.17.7 introduced `animatesUrlAttribute()` to block SVG animation elements (`animate`, `animateColor`, `animateMotion`, `animateTransform`, `set`) when their `attributeName` targets a URL sink like `href`. However, this check is bypassed when the animation element uses a namespace prefix (e.g., `svg:animate` instead of `animate`). ## Root Cause The `animatesUrlAttribute` function (index.js, line ~832) checks `svgAnimationTags.indexOf(name.toLowerCase())`, where `svgAnimationTags` contains bare local names: `["animate", "animatecolor", "animatemotion", "animatetransf
  • >= 2.17.7, < 2.18.0
GitHub (opens in a new tab)
GHSA-cv27-6wvh-8x7jModerateApostropheCMS: Incomplete CVE-2026-53606: `meta http-equiv=refresh` `content` still ships `javascript:` / `data:` URLs### Summary CVE-2026-53606 expanded `allowedSchemesAppliedToAttributes` so named URL attributes (`action`, `formaction`, `data`, `poster`, `background`, later `ping`, `xlink:href`, …) go through `naughtyHref()`. A **URL nested inside `meta` `content`** (`http-equiv=refresh`) is not an attribute name on that list, so the embedded destination is never scheme-checked. Default `allowedTags` still omit `meta`. Same non-default integrator config as 53606: allow `meta` plus `http-equiv` / `content`. On **2.17.7**: ```text sanitizeHtml( '<meta http-equiv="refresh" content="0;url=javascript:alert
  • < 2.18.0
GitHub (opens in a new tab)
GHSA-x3q4-9hxx-gx8mModerateApostropheCMS sanitize-html: nonTextTags discard region ends early on an implied close, letting <noscript> content render## Summary `sanitize-html` discards the *content* of every element in `nonTextTags`. It delimits that region using htmlparser2's close events, and ignores the `isImplied` flag htmlparser2 passes it. Closing a still-open **ancestor** from inside a `<noscript>` makes htmlparser2 unwind its stack past the `noscript`; the synthetic implied close it emits on the way ends the discard region early, and everything after it is treated as ordinary body content. A browser with scripting enabled parses `<noscript>` content as **raw text**, so the same markup renders as inert text there. The sanitizer th
  • < 2.18.0
GitHub (opens in a new tab)
GHSA-jxwj-j7wr-gfrwModerateApostropheCMS: Mutation-XSS / allowedTags bypass via literal `</textarea/>` solidus close### Summary A mutation-XSS / allowedTags bypass: when `textarea` (or `xmp`) is included in `allowedTags`, an input containing a literal `</textarea/>` (a solidus right after the RCDATA end-tag name) lets non-allowed markup such as `<img src=x onerror=…>` pass through `sanitizeHtml()` **live and unescaped**, even though `img`/`onerror` are not in the allowlist. A spec-compliant browser executes the surviving handler — XSS. This is a literal-solidus variant that bypasses the two most recent fixes in this code area (CVE-2026-40186, CVE-2026-44990), both already applied in 2.17.5. The default conf
  • < 2.17.6
GitHub (opens in a new tab)
GHSA-g8qq-57p8-ggw5ModerateApostropheCMS: Stored XSS via SVG SMIL URI-list scheme-policy bypass### Summary When SVG animation is allowed, `attributeName="href"` makes `values` a list of URL destinations. `sanitize-html` accepts a list that starts with a safe fragment even when `values` is explicitly scheme-checked, allowing a later `javascript:` destination to execute when the sanitized link is activated. ### Details `index.js:371-383` validates each attribute as one flat URL. It does not recognize that `attributeName="href"` gives the sibling `values` attribute SMIL URI-list semantics. For `values="#safe;javascript:..."`, the leading fragment passes the flat check and the complete lis
  • >= 1.9.0, < 2.17.7
GitHub (opens in a new tab)
GHSA-vccv-cmxp-4j9hModeratesanitize-html has incomplete URI scheme validation in that allows javascript: URIs through action, formaction, data, poster, and background attributes## Summary sanitize-html uses `allowedSchemesAppliedToAttributes` (default: `['href', 'src', 'cite']`) to gate the `naughtyHref()` function that blocks dangerous URI schemes like `javascript:` and `vbscript:`. The HTML specification defines 10+ attributes that accept URIs (`action`, `formaction`, `data`, `poster`, `background`, `ping`, `xlink:href`, `dynsrc`, `lowsrc`), but none of these are included in the default gate list. When a developer allows any of these attributes in their configuration, `javascript:` URIs pass through completely unmodified, enabling XSS. The library has zero awaren
  • >= 1.18.0, < 2.17.5
GitHub (opens in a new tab)
GHSA-rpr9-rxv7-x643CriticalApostrophe has default XSS via `xmp` raw-text passthrough in `sanitize-html`### Summary Under the default configuration, `sanitize-html` can turn attacker-controlled content inside a disallowed `xmp` element into live HTML or JavaScript. This is a sanitizer bypass in the default `disallowedTagsMode: 'discard'` path and can lead to stored XSS in applications that render sanitized output back to users. ### Details In `sanitize-html@2.17.3`, the default `nonTextTags` list includes only `script`, `style`, `textarea`, and `option` in `index.js` lines 138-142. That means disallowed `xmp` tags are not treated as "drop the entire contents" tags. Later, in the `ontext` handl
  • >= 2.17.3, < 2.17.4
GitHub (opens in a new tab)
GHSA-9mrh-v2v3-xpfmModeratesanitize-html allowedTags Bypass via Entity-Decoded Text in nonTextTags Elements## Summary Commit 49d0bb7 introduced a regression in sanitize-html that bypasses `allowedTags` enforcement for text inside `nonTextTagsArray` elements (`textarea` and `option`). Entity-encoded HTML inside these elements passes through the sanitizer as decoded, unescaped HTML, allowing injection of arbitrary tags including XSS payloads. This affects any application using sanitize-html that includes `option` or `textarea` in its `allowedTags` configuration. ## Details The vulnerable code is at `packages/sanitize-html/index.js:569-573`: ```javascript } else if ((options.disallowedTagsMode ===
  • >= 2.17.2, < 2.17.3
GitHub (opens in a new tab)
GHSA-qhxp-v273-g94hModeratesanitize-html is vulnerable to XSS through incomprehensive sanitization`sanitize-html` prior to version 2.0.0-beta is vulnerable to Cross-site Scripting (XSS). The `sanitizeHtml()` function in `index.js` does not sanitize content when using the custom `transformTags` option, which is intended to convert attribute values into text. As a result, malicious input can be transformed into executable code.
  • < 2.0.0-beta
GitHub (opens in a new tab)
  • GHSA-c9rx-x947-fp3hModerate
    ApostropheCMS sanitize-html: unbounded recursion when re-sanitizing the fallback of a discarded iframe (stack overflow, nestingLimit not enforced)
    • >= 2.18.0, < 2.18.1

    ### Summary Since 2.18.0, when an `<iframe>` is not allowed and `disallowedTagsMode` is `'discard'` (the defaults), its raw-text content is re-sanitized by a recursive call to `sanitizeHtml(text, options)` (the change from #5564, fixing #5550). The recursion has no bound and starts each nested call with a fresh state. Two consequences, both absent from 2.17.7 and 2.17.4: 1. A few kilobytes of unclosed `<iframe>` tags throw `RangeError: Maximum call stack size exceeded` with the default options. Any application that sanitizes untrusted HTML with 2.18.0 can be made to throw on a small cr

    CVE: CVE-2026-113650

  • GHSA-374f-7chj-9948Low
    ApostropheCMS sanitize-html: SMIL animation namespace-prefix bypass allows javascript: URI injection (XSS)
    • >= 2.17.7, < 2.18.0

    ## Summary sanitize-html 2.17.7 introduced `animatesUrlAttribute()` to block SVG animation elements (`animate`, `animateColor`, `animateMotion`, `animateTransform`, `set`) when their `attributeName` targets a URL sink like `href`. However, this check is bypassed when the animation element uses a namespace prefix (e.g., `svg:animate` instead of `animate`). ## Root Cause The `animatesUrlAttribute` function (index.js, line ~832) checks `svgAnimationTags.indexOf(name.toLowerCase())`, where `svgAnimationTags` contains bare local names: `["animate", "animatecolor", "animatemotion", "animatetransf

    CVE: CVE-2026-113657

  • GHSA-cv27-6wvh-8x7jModerate
    ApostropheCMS: Incomplete CVE-2026-53606: `meta http-equiv=refresh` `content` still ships `javascript:` / `data:` URLs
    • < 2.18.0

    ### Summary CVE-2026-53606 expanded `allowedSchemesAppliedToAttributes` so named URL attributes (`action`, `formaction`, `data`, `poster`, `background`, later `ping`, `xlink:href`, …) go through `naughtyHref()`. A **URL nested inside `meta` `content`** (`http-equiv=refresh`) is not an attribute name on that list, so the embedded destination is never scheme-checked. Default `allowedTags` still omit `meta`. Same non-default integrator config as 53606: allow `meta` plus `http-equiv` / `content`. On **2.17.7**: ```text sanitizeHtml( '<meta http-equiv="refresh" content="0;url=javascript:alert

    CVE: CVE-2026-113661

  • GHSA-x3q4-9hxx-gx8mModerate
    ApostropheCMS sanitize-html: nonTextTags discard region ends early on an implied close, letting <noscript> content render
    • < 2.18.0

    ## Summary `sanitize-html` discards the *content* of every element in `nonTextTags`. It delimits that region using htmlparser2's close events, and ignores the `isImplied` flag htmlparser2 passes it. Closing a still-open **ancestor** from inside a `<noscript>` makes htmlparser2 unwind its stack past the `noscript`; the synthetic implied close it emits on the way ends the discard region early, and everything after it is treated as ordinary body content. A browser with scripting enabled parses `<noscript>` content as **raw text**, so the same markup renders as inert text there. The sanitizer th

    CVE: CVE-2026-113654

  • GHSA-jxwj-j7wr-gfrwModerate
    ApostropheCMS: Mutation-XSS / allowedTags bypass via literal `</textarea/>` solidus close
    • < 2.17.6

    ### Summary A mutation-XSS / allowedTags bypass: when `textarea` (or `xmp`) is included in `allowedTags`, an input containing a literal `</textarea/>` (a solidus right after the RCDATA end-tag name) lets non-allowed markup such as `<img src=x onerror=…>` pass through `sanitizeHtml()` **live and unescaped**, even though `img`/`onerror` are not in the allowlist. A spec-compliant browser executes the surviving handler — XSS. This is a literal-solidus variant that bypasses the two most recent fixes in this code area (CVE-2026-40186, CVE-2026-44990), both already applied in 2.17.5. The default conf

    CVE: CVE-2026-63670

  • GHSA-g8qq-57p8-ggw5Moderate
    ApostropheCMS: Stored XSS via SVG SMIL URI-list scheme-policy bypass
    • >= 1.9.0, < 2.17.7

    ### Summary When SVG animation is allowed, `attributeName="href"` makes `values` a list of URL destinations. `sanitize-html` accepts a list that starts with a safe fragment even when `values` is explicitly scheme-checked, allowing a later `javascript:` destination to execute when the sanitized link is activated. ### Details `index.js:371-383` validates each attribute as one flat URL. It does not recognize that `attributeName="href"` gives the sibling `values` attribute SMIL URI-list semantics. For `values="#safe;javascript:..."`, the leading fragment passes the flat check and the complete lis

    CVE: CVE-2026-84371

  • GHSA-vccv-cmxp-4j9hModerate
    sanitize-html has incomplete URI scheme validation in that allows javascript: URIs through action, formaction, data, poster, and background attributes
    • >= 1.18.0, < 2.17.5

    ## Summary sanitize-html uses `allowedSchemesAppliedToAttributes` (default: `['href', 'src', 'cite']`) to gate the `naughtyHref()` function that blocks dangerous URI schemes like `javascript:` and `vbscript:`. The HTML specification defines 10+ attributes that accept URIs (`action`, `formaction`, `data`, `poster`, `background`, `ping`, `xlink:href`, `dynsrc`, `lowsrc`), but none of these are included in the default gate list. When a developer allows any of these attributes in their configuration, `javascript:` URIs pass through completely unmodified, enabling XSS. The library has zero awaren

    CVE: CVE-2026-53606

  • GHSA-rpr9-rxv7-x643Critical
    Apostrophe has default XSS via `xmp` raw-text passthrough in `sanitize-html`
    • >= 2.17.3, < 2.17.4

    ### Summary Under the default configuration, `sanitize-html` can turn attacker-controlled content inside a disallowed `xmp` element into live HTML or JavaScript. This is a sanitizer bypass in the default `disallowedTagsMode: 'discard'` path and can lead to stored XSS in applications that render sanitized output back to users. ### Details In `sanitize-html@2.17.3`, the default `nonTextTags` list includes only `script`, `style`, `textarea`, and `option` in `index.js` lines 138-142. That means disallowed `xmp` tags are not treated as "drop the entire contents" tags. Later, in the `ontext` handl

    CVE: CVE-2026-44990

  • GHSA-9mrh-v2v3-xpfmModerate
    sanitize-html allowedTags Bypass via Entity-Decoded Text in nonTextTags Elements
    • >= 2.17.2, < 2.17.3

    ## Summary Commit 49d0bb7 introduced a regression in sanitize-html that bypasses `allowedTags` enforcement for text inside `nonTextTagsArray` elements (`textarea` and `option`). Entity-encoded HTML inside these elements passes through the sanitizer as decoded, unescaped HTML, allowing injection of arbitrary tags including XSS payloads. This affects any application using sanitize-html that includes `option` or `textarea` in its `allowedTags` configuration. ## Details The vulnerable code is at `packages/sanitize-html/index.js:569-573`: ```javascript } else if ((options.disallowedTagsMode ===

    CVE: CVE-2026-40186

  • GHSA-qhxp-v273-g94hModerate
    sanitize-html is vulnerable to XSS through incomprehensive sanitization
    • < 2.0.0-beta

    `sanitize-html` prior to version 2.0.0-beta is vulnerable to Cross-site Scripting (XSS). The `sanitizeHtml()` function in `index.js` does not sanitize content when using the custom `transformTags` option, which is intended to convert attribute values into text. As a result, malicious input can be transformed into executable code.

    CVE: CVE-2019-25225

Showing 1-10 of 17 vulnerabilities