CVE-2026-84371 Overview
CVE-2026-84371 is a stored cross-site scripting (XSS) vulnerability in the sanitize-html package bundled with ApostropheCMS, an open-source Node.js content management system. The flaw affects sanitize-html versions 1.9.0 through 2.17.6 and stems from incomplete handling of Scalable Vector Graphics (SVG) Synchronized Multimedia Integration Language (SMIL) animation semantics in packages/sanitize-html/index.js. When configurations permit SVG animation elements, an attacker can smuggle an executable URL past scheme validation. The issue is fixed in version 2.17.7. This vulnerability is categorized under [CWE-79] Improper Neutralization of Input During Web Page Generation.
Critical Impact
An authenticated attacker who can submit sanitized SVG content can execute JavaScript in the application's origin when a victim activates a crafted link.
Affected Products
- ApostropheCMS sanitize-html package, versions 1.9.0 through 2.17.6
- ApostropheCMS deployments allowing animate, animateColor, animateMotion, animateTransform, or set SVG elements
- Downstream applications embedding the vulnerable sanitize-html fork
Discovery Timeline
- 2026-09-01 - CVE-2026-84371 published to NVD
- 2026-09-02 - Last updated in NVD database
Technical Details for CVE-2026-84371
Vulnerability Analysis
The vulnerability resides in how sanitize-html inspects attribute values on SVG SMIL animation elements. The sanitizer validates the values attribute as a single flat URL string. It does not model the SMIL semantics where an attributeName of href or xlink:href causes each entry in the sibling values, from, to, or by list to be applied to the animated element's link target.
An attacker supplies a values list whose first entry is a safe fragment such as a relative anchor. Later entries in the list contain an executable destination using a scheme like javascript:. Because the sanitizer only evaluates the composite string against allowedSchemesAppliedToAttributes, the malicious later value survives filtering. When the browser renders the SVG and executes the animation, it copies the later destination into the live href attribute of the target element. A victim who activates that link triggers script execution in the application's origin.
Root Cause
The sanitizer treats animation URL sinks as flat values instead of recognizing SMIL retargeting. Animation elements do not carry a URL themselves; they modify another element's attribute named by attributeName. The pre-patch code lacked awareness of this indirection, allowing multi-value URL lists to bypass scheme allowlists.
Attack Vector
Exploitation requires an attacker with content-submission privileges and a victim who interacts with the rendered link. The patch introduces explicit recognition of SMIL animation tags and treats href as an always-URL attribute regardless of namespace prefix.
// Source: https://github.com/apostrophecms/apostrophe/commit/1135516a1a4a8f9638641c460488a43d8af20081
// Patch in packages/sanitize-html/index.js
// Tags that are inherently vulnerable to being used in XSS attacks.
const vulnerableTags = [ 'script', 'style' ];
// SVG SMIL animation elements. These do not carry a URL themselves: they
// retarget an attribute of another element, naming it with `attributeName`
// and supplying the new value(s) in `values`, `from`, `to` and `by`.
const svgAnimationTags = [
'animate', 'animatecolor', 'animatemotion', 'animatetransform', 'set'
];
// Attribute names that always name a URL sink, whatever
// `allowedSchemesAppliedToAttributes` has been narrowed to. A namespace prefix
// is ignored when matching, so `xlink:href` and any other prefixed spelling of
// `href` are covered.
const alwaysUrlAttributes = [ 'href' ];
Detection Methods for CVE-2026-84371
Indicators of Compromise
- SVG payloads submitted through content editors containing <animate>, <animateColor>, <animateMotion>, <animateTransform>, or <set> elements with attributeName="href" or attributeName="xlink:href"
- values, from, to, or by attributes containing javascript:, data:, or vbscript: scheme strings mixed with benign fragments
- Outbound requests or client-side script execution originating from links inside rendered SVG content
Detection Strategies
- Audit stored content in ApostropheCMS collections for SVG markup referencing SMIL animation tags targeting URL attributes
- Deploy web application firewall (WAF) rules that flag SVG uploads containing animation elements with URL-scheme literals in multi-value attribute lists
- Inspect Content Security Policy (CSP) violation reports for script-src or navigate-to blocks tied to link activation on user-generated pages
Monitoring Recommendations
- Log and alert on rendering paths that emit SVG containing animate* or set elements from untrusted authors
- Correlate content-management API writes with subsequent anomalous outbound navigations from viewer sessions
- Track version metadata of the sanitize-html dependency across build pipelines to confirm patched releases are deployed
How to Mitigate CVE-2026-84371
Immediate Actions Required
- Upgrade the ApostropheCMS sanitize-html package to version 2.17.7 or later across all environments
- Review sanitizer configuration and remove animate, animateColor, animateMotion, animateTransform, and set from allowedTags where the feature is not required
- Revoke or review content-submission privileges for untrusted authors until patched builds are in production
Patch Information
The fix is delivered in ApostropheCMS sanitize-html version 2.17.7. Review the Apostrophe CMS Changelog, the fix commit 1135516, and GitHub Security Advisory GHSA-g8qq-57p8-ggw5 for merge details. Reconciliation changes appear in Pull Request #5552 and commit 38ff1106.
Workarounds
- Strip SVG SMIL animation elements from allowed tag lists in the sanitizer configuration
- Enforce a strict Content Security Policy that forbids javascript: URLs and inline script execution on rendered content pages
- Serve user-submitted SVG from a sandboxed origin isolated from authenticated session cookies
# Configuration example: pin the patched version
npm install sanitize-html@2.17.7
# Verify installed version
npm ls sanitize-html
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

