CVE-2026-113657

lowpriority · track · 0EPSS 0.003 · 24 %ileUS
grimoire priorityP3 · Track
Exploitable?
—
no known exploitation
Likely / severe?
0.31% (24th) EPSS
CVSS 3.7 · low
Is it mine?
1 products
Check your exposure
Who says so?
1 sources
osv

EPSS · scored 2026-10-28

ApostropheCMS is an open-source Node.js content management system, and sanitize-html provides a simple HTML sanitizer with a clear API. From sanitize-html 2.17.7 until 2.18.0, an application configuration that permits namespace-prefixed SVG animation elements and the relevant URL-targeting attributes can bypass the SMIL URL protection because prefixed tag names do not match the unprefixed animation-element check. The bypass can rewrite a link destination to an unsafe URI after the sanitized SVG is rendered, with script execution occurring when a user activates the affected link; the default sanitizer configuration is not unconditionally affected. This issue is fixed in sanitize-html 2.18.0.

01

cvss

Technical severity, 0–10. One row per scoring source.

3.7
010

base score 0–10 · higher = more severe · hover a vector to decode

v3.13.7lowCVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:Nsecondary · security-advisories@github.comexploitability 1.2 · impact 2.5
v3.13.7lowCVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:Nsecondary · OSV
v3.13.4lowCVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:N/E:Usecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: poc · Automatable: no · Technical Impact: partialcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (1)

Products and version ranges known to be affected.

05

advisories (1)

Vendor and ecosystem advisories describing this.

  • GHSA-374f-7chj-9948ApostropheCMS sanitize-html: SMIL animation namespace-prefix bypass allows javascript: URI injection (XSS)2026-10-20ghsa · osvUS

    ## 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", "animatetransform", "set"]`. htmlparser2 passes namespace-prefixed tag names verbatim, so `svg:animate` does not match `animate` in the array, causing the function to return `false` and skip the SMIL XSS protection. Ironically, the function already handles namespace prefixes correctly for the `attributeName` target value (line ~843): `const localName = target.slice(target.lastIndexOf(":") + 1)` — but this same stripping was not applied to the tag name itself. ## Proof of Concept ```javascript const sanitizeHtml = require("sanitize-html"); const config = { allowedTags: false, allowedAttributes: false, allowedSchemes: ["http", "https"] }; // Standard animate — BLOCKED by 2.17.7 fix const blocked = sanitizeHtml( `<svg><a href="#safe"><animate attributeName="href" values="#safe;javascript:alert(1)" dur=".01s" fill="freeze"/><text>Click</text></a></svg>`, config ); console.log("Standard animate:", blocked.includes("javascript:") ? "BYPASS" : "BLOCKED"); // Output: BLOCKED // Namespace-prefixed animate — BYPASSES the fix const bypassed = sanitizeHtml( `<svg><a href="#safe"><svg:animate attributeName="href" values="#safe;javascript:alert(document.domain)" dur=".01s" fill="freeze"/><text>Click</text></a></svg>`, config ); console.log("svg:animate:", bypassed.includes("javascript:") ? "BYPASS" : "BLOCKED"); // Output: BYPASS ``` All 5 SMIL animation elements are bypassable with any namespace prefix (`svg:`, `xlink:`, `xml:`, uppercase variants). Tested and confirmed on sanitize-html 2.17.7 from the apostrophe monorepo. ## Impact Cross-site scripting (XSS) via SMIL animation retargeting. When an application uses `allowedTags: false` (common in rich-text editors that want to preserve SVG), an attacker can inject `<svg:animate attributeName="href" values="#safe;javascript:..." .../>` to override the `href` attribute of a parent `<a>` element after the page loads, causing the link to execute JavaScript when clicked. ## Suggested Fix Strip the namespace prefix from the tag name before the lookup, matching the pattern already used for the attribute name target: ```javascript // Before (vulnerable): if (svgAnimationTags.indexOf(name.toLowerCase()) === -1) { // After (fixed): const localTagName = name.toLowerCase().slice(name.lastIndexOf(":") + 1); if (svgAnimationTags.indexOf(localTagName) === -1) { ``` ## Affected Versions sanitize-html >= 2.17.7 (where the SMIL animation protection was introduced). Earlier versions lack the SMIL protection entirely. ## Credit Kai Aizen (SnailSploit) — Adversarial AI & Security Research

06

sources

Which sources assert this record, and when.

published 2026-10-20modified 2026-10-20
07

references (4) nvd

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan