Skip to main content

sanitize-html CVE-2026-113650

| EUVDEUVD-2026-105176 MEDIUM
Uncontrolled Recursion (CWE-674)
2026-10-20 GitHub_M GHSA-c9rx-x947-fp3h
5.3
CVSS 3.1 · Vendor: GitHub_M
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Submit crafted HTML to sanitizer endpoint
  2. Exploit
    Disallowed iframe raw-text triggers recursive sanitize call
  3. Execution
    Unbounded recursion consumes call stack
  4. Impact
    Stack exhaustion disrupts Node.js request/service

Vulnerability Assessment

Weakness
CWE
ASVS 5.0
V15 - Secure Coding and Architecture Recursion depth limits
Exploitation Conditions

Exploitation requires that the application feeds attacker-influenced HTML into sanitize-html 2.18.0 while running the default configuration - specifically with <iframe> NOT in allowedTags and disallowedTagsMode set to 'discard' (both are the library defaults), so most unmodified deployments are exposed. The payload must contain a disallowed <iframe> whose raw-text content nests deeply enough to overflow the Node.js call stack. Limiting factors: there must exist an application path that routes untrusted HTML to sanitizeHtml (e.g. a public comment/form or an editor input); deployments that explicitly allow iframes or set disallowedTagsMode to a non-'discard' mode avoid the recursive path; and impact is confined to availability (a failed request or stack-overflow error), with no data exposure. Per CVSS PR:N the flaw is reachable without authentication, though in ApostropheCMS the HTML-submission surface may in practice sit behind editor permissions depending on where sanitize-html is invoked.

Impact

This is a genuine but moderate-severity denial-of-service issue, not a critical priority. The CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L, base 5.3) correctly signals a remotely reachable, low-complexity, unauthenticated flaw whose only impact is low availability - there is no confidentiality or integrity exposure (C:N/I:N). The root cause (CWE-674 uncontrolled recursion in sanitize-html 2.18.0: a disallowed <iframe> under the default disallowedTagsMode 'discard' re-sanitizes its raw-text content via an unbounded recursive sanitizeHtml call) can exhaust the Node.js call stack. No EPSS score, CISA KEV entry, or public POC was provided in the intelligence set, so there is no public exploit identified at time of analysis and no evidence of active exploitation. NOTE A CONFLICT: the input tag 'Information Disclosure' contradicts the CVSS vector, which shows zero confidentiality/integrity impact and only availability impact - the CWE-674 mechanism is a resource-exhaustion DoS, so the tag appears mislabeled and should not drive triage. Overall this warrants routine patching (trivial exploit, wide library footprint) rather than emergency response, because worst-case impact is a crashed request or process, not data loss.

Exploit ScenarioDerived

An attacker submits crafted HTML - for example through a comment, form field, or rich-text input that an application passes to sanitize-html with its default options - in which a disallowed <iframe> contains deeply nested raw-text content. Because the sanitizer recursively re-sanitizes that content without any depth bound, the Node.js call stack is exhausted, throwing a stack-overflow error that fails the request or can disrupt the service. No public exploit code was provided, but the trigger is simple to construct once the mechanism is known.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.3% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 20, 2026

Unbounded recursive re-sanitization in sanitize-html 2.18.0 allows remote attackers to exhaust the Node.js call stack and crash the process by submitting HTML containing a disallowed <iframe> with deeply nested raw-text content. The flaw triggers only under the library defaults - <iframe> absent from allowedTags and disallowedTagsMode set to 'discard' - which means most unmodified deployments, including ApostropheCMS installations that route untrusted HTML through the sanitizer, are exposed. Impact is limited to availability (CVSS 5.3, A:L only, PR:N/AC:L/UI:N) with no confidentiality or integrity effect, and no public exploit code or CISA KEV active-exploitation entry was identified at time of analysis.

RemediationAI

Vendor-released patch: sanitize-html 2.18.1 - upgrade the dependency to that version (release tag https://github.com/apostrophecms/apostrophe/releases/tag/sanitize-html@2.18.1) and, for ApostropheCMS deployments, update the CMS to a release containing commits 06e4b377f3c360f9e89c32dccd7e505ad5ddf498 and 40b989b1a9dd23d30029b8ce7668634265cfe5ea as described in advisory GHSA-c9rx-x947-fp3h; verify with a lockfile or dependency-tree audit since sanitize-html is often a transitive dependency. If immediate upgrade is not possible, the most targeted workaround is to set disallowedTagsMode to 'escape' (or 'recursiveEscape') in every sanitize-html options object, which bypasses the recursive re-sanitization path entirely; the trade-off is that disallowed tags are rendered as visible escaped text rather than silently stripped, which can change page output and, for content like malformed markup, expose raw angle brackets to readers. A secondary compensating control is to reject or strip <iframe> blocks and cap input length before HTML reaches the sanitizer, trading completeness for reduced attack surface, and to run sanitization in a worker/child process so a stack overflow does not take down the main HTTP process. Do not simply add <iframe> to allowedTags as a fix - it re-enables iframe-based content injection risks that the default configuration was designed to avoid.

Affected VersionsENISA

sanitize-html 2.18.0, < 2.18.1
Apostrophe < 4.34.0

Affected Packages

npm sanitize-html fix: 2.18.1
euvd apostrophe fix: 4.34.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in npm, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

sanitize-html is an npm package built on the htmlparser2 parser and is widely used, directly or transitively, by Node.js frameworks and CMSs. The affected CPE strings cover both apostrophecms:apostrophe and apostrophecms:sanitize-html, reflecting that the library ships inside ApostropheCMS as well as standalone. Under CWE-674 (Uncontrolled Recursion), when a tag is disallowed and disallowedTagsMode is 'discard' (both defaults), sanitize-html treats the content of raw-text elements such as <iframe> as text that must itself be re-sanitized, invoking sanitizeHtml(text, options) recursively. Each nested invocation initializes a fresh parser and state rather than inheriting a shared depth counter, so there is no ceiling on recursion depth and no accumulated state that would cut it off; sufficiently deep nesting overflows the V8 call stack and throws a RangeError. Because Node.js serves requests on a single event-loop thread, an uncaught stack overflow from a request-scoped sanitize call can abort the request or the worker process, producing the assessed availability-only impact. Deployments that explicitly allow iframes, or that set disallowedTagsMode to 'escape'/'recursiveEscape', never enter the recursive code path.

Know when Apostrophecms gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (GitHub_M) PRIMARY 5.3 MEDIUM
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
vuln.today AI 5.3 MEDIUM

Remotely reachable HTML input with no privileges or interaction (AV:N/AC:L/PR:N/UI:N); unbounded recursion causes stack exhaustion yielding only availability loss (A:L), with no confidentiality or integrity impact.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
Red Hat 5.3 MEDIUM

Primary rating from Vendor (GitHub_M).

CVSS VectorVendor: GitHub_M

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
Low

Lifecycle Timeline

2
Patch available
Oct 20, 2026 - 18:17 EUVD
CVE Published
Oct 20, 2026 - 16:19 cve.org
MEDIUM 5.3

DescriptionCVE.org

ApostropheCMS is an open-source Node.js content management system. In sanitize-html 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 recursion has no bound and starts each nested call with a fresh state. This vulnerability is fixed in 2.18.1.

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 108 npm packages depend on sanitize-html (28 direct, 83 indirect)

Ecosystem-wide dependent count for version 2.18.0.

Threat Intelligence Overview

EPSS Score
0.3%
Top 78% exploitable
Prevalence
High
sanitize-html is a very widely deployed npm HTML sanitization library
Threat Intel
1
1 source
Social Media
1
Sightings
Data Quality
7 sources
Confidence: High

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC No
EPSS 0.3%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
None
System Exposure· derived
Open
Automatable· derived
Yes
Human Impact· derived
High

Priority Score

26
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +26
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0
CVE-2026-63669 MEDIUM POC
6.5 Aug 17

Integrity bypass in ApostropheCMS page management allows authenticated low-privileged editors to move pages into restric

CVE-2026-63670 MEDIUM POC
6.1 Aug 17

Stored cross-site scripting in ApostropheCMS prior to 2.17.6 enables execution of arbitrary JavaScript in victim browser

CVE-2014-125128 MEDIUM POC
6.1 Sep 08

'sanitize-html' prior to version 1.0.3 is vulnerable to Cross-site Scripting (XSS). Rated medium severity (CVSS 6.1), th

CVE-2019-25225 MEDIUM POC
6.1 Sep 08

`sanitize-html` prior to version 2.0.0-beta is vulnerable to Cross-site Scripting (XSS). Rated medium severity (CVSS 6.1

CVE-2021-25979 CRITICAL
9.8 Nov 08

Apostrophe CMS versions prior to 3.3.1 did not invalidate existing login sessions when disabling a user account or chang

CVE-2026-84371 MEDIUM POC
5.4 Sep 01

Stored XSS in sanitize-html versions 1.9.0 through 2.17.6 allows authenticated low-privileged users to inject executable

CVE-2024-21501 MEDIUM POC
5.3 Feb 24

Versions of the package sanitize-html before 2.12.1 are vulnerable to Information Exposure when used on the backend and

CVE-2021-26540 MEDIUM POC
5.3 Feb 08

Apostrophe Technologies sanitize-html before 2.3.2 does not properly validate the hostnames set by the "allowedIframeHos

CVE-2021-26539 MEDIUM POC
5.3 Feb 08

Apostrophe Technologies sanitize-html before 2.3.1 does not properly handle internationalized domain name (IDN) which co

CVE-2026-53609 CRITICAL
9.1 Jun 12

Prototype pollution in ApostropheCMS versions up to and including 4.30.0 allows an authenticated editor to poison Object

CVE-2026-53608 HIGH
8.7 Jun 12

Stored cross-site scripting in the @apostrophecms/seo plugin (versions ≤1.4.2) allows any user holding the default edito

CVE-2026-35569 HIGH
8.7 Apr 15

Stored cross-site scripting in ApostropheCMS SEO fields permits an authenticated attacker to inject arbitrary JavaScript

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy