CVE-2026-63670
mediumpriority · track · 0EPSS 0.003 · 26 %ileDEEUUSEPSS · scored 2026-10-27
ApostropheCMS is an open-source Node.js content management system. Prior to 2.17.6, sanitizeHtml() can pass disallowed executable markup through packages/sanitize-html/index.js when textarea or xmp is included in allowedTags because a literal solidus after the raw-text end-tag name is treated as text by htmlparser2 and the ontext handler emits that content without escaping, while a browser parses the following img onerror markup as active HTML. This issue is fixed in version 2.17.6.
cvss
Technical severity, 0–10. One row per scoring source.
base score 0–10 · higher = more severe · hover a vector to decode
ssvc
A stakeholder decision — act, attend, or track — from exploitation and impact.
weaknesses
The CWE weakness classes this flaw belongs to.
affected products (7)
Products and version ranges known to be affected.
- IBM WebSphere Service Registry and Repositoryall versionscert_bundDEcpe:/a:ibm:websphere_service_registry_and_repository:-
advisories (2)
Vendor and ecosystem advisories describing this.
- WID-SEC-W-2026-3596IBM App Connect Enterprise: Mehrere SchwachstellenDeutsch2026-09-27csaf · cert_bundDE
Ein Angreifer kann mehrere Schwachstellen in IBM App Connect Enterprise ausnutzen, um Sicherheitsvorkehrungen zu umgehen, um einen Denial of Service Angriff durchzuführen, um Informationen offenzulegen, um Dateien zu manipulieren und um einen Cross-Site Scripting Angriff durchzuführen.
- GHSA-jxwj-j7wr-gfrwApostropheCMS: Mutation-XSS / allowedTags bypass via literal `</textarea/>` solidus close2026-09-03ghsa · osvUS
### 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 configuration is not affected. ### Details `sanitize-html` emits the text content of HTML raw-text elements (`textarea`, `xmp`) without escaping. Two things combine: - **Parser differential:** on input, htmlparser2 does NOT recognize `</textarea/>` (solidus after the RCDATA end-tag name) as a close tag; it emits `</textarea/><img …>` as a single raw-text node. - **Unescaped passthrough:** the `ontext` handler (`index.js` ~575-583) appends `textarea`/`xmp` content with `result += text` (no `escapeHtml`), assuming it is "already properly encoded" — true for entity-decoded content (what CVE-2026-40186 fixed) but false for this mis-tokenized literal close tag. A spec browser treats `</textarea/>` as a valid `textarea` close, so the following `<img onerror>` is parsed as a live element. The recent fixes addressed entity-encoding (CVE-2026-40186) and the `xmp` default (CVE-2026-44990); neither covers the literal-solidus mis-tokenization, so the raw passthrough still leaks. ### PoC ```js // npm i sanitize-html@2.17.5 parse5 && node poc.js const sanitizeHtml = require('sanitize-html'); const input = '<textarea></textarea/><img src=x onerror="alert(document.domain)">'; const opts = { allowedTags: sanitizeHtml.defaults.allowedTags.concat(['textarea']) }; // img NOT allowed console.log(sanitizeHtml(input, opts)); // => <textarea></textarea/><img src=x onerror="alert(document.domain)"></textarea> // the <img onerror> survives live and unescaped console.log(sanitizeHtml(input)); // default config (no textarea allowed) => "" (safe) ``` Re-parsing the sanitized OUTPUT with **parse5** (the WHATWG HTML parser browsers/jsdom use) yields a **live `<img src=x onerror=alert(document.domain)>`** at `body` level (it escaped the textarea RCDATA, not inert text) → the `onerror` fires in a browser. Confirmed on 2.17.5 (Node v24). A canonical `poc.js` is attached. <img width="650" height="118" alt="image" src="https://github.com/user-attachments/assets/d63bb5b7-ba3e-4b0e-a821-86a453ea0352" /> ### Impact Cross-site scripting (CWE-79). Requires `textarea` (or `xmp`) in `allowedTags` — a benign-looking, common addition in form builders, CMS, and rich-text editors. Adding a harmless tag that then enables XSS via *non-allowed* `img`/`onerror` breaks the sanitizer's core contract; the maintainers have fixed this class before (e.g. GHSA-9mrh). An attacker who can submit content rendered through such a configuration achieves stored/reflected XSS (cookie theft, session hijack). Severity Medium (default config is safe; user interaction to view the page). **Suggested fix:** route `textarea`/`xmp` content through `escapeHtml` instead of the raw passthrough, and/or fix the htmlparser2 `</tag/>` RCDATA end-tag tokenization to match the WHATWG spec.
also known as (1)
Other names and identifiers for this entity.
sources
Which sources assert this record, and when.
references (6)
External citations — patches, advisories, analysis.
- https://github.com/apostrophecms/apostrophe/commit/eae1fb2b72ec5d1c27d0977509c6482a0408f725enisa_euvd
- https://github.com/apostrophecms/apostrophe/pull/5501enisa_euvd
- https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-jxwj-j7wr-gfrwenisa_euvd
- https://github.com/apostrophecms/apostrophe/commit/eae1fb2b72ec5d1c27d0977509c6482a0408f725nvd
- https://github.com/apostrophecms/apostrophe/pull/5501nvd
- https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-jxwj-j7wr-gfrwnvd
Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.
Free scan