Register for the AI for Security Summit: Join Figma, Perplexity & Wiz

CVE-2026-84371
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-84371 is a stored Cross-Site Scripting (XSS) vulnerability in the sanitize-html package bundled within ApostropheCMS, caused by a URL scheme policy bypass via SVG SMIL animation elements. Affecting versions >= 1.9.0 and <= 2.17.6, the flaw allows authenticated attackers to craft SVG content with animation elements (e.g., animate, animateColor, animateMotion, animateTransform, or set) that smuggle executable javascript: URLs past the sanitizer's scheme-checking logic. The vulnerability was disclosed on September 1, 2026, and patched in version 2.17.7 released August 13, 2026. It carries a CVSS v3.1 base score of 5.4 (Medium) (GitHub Advisory).

Technical details

The root cause (CWE-79) lies in packages/sanitize-html/index.js (lines 371–383), which validates animation values, from, to, and by attributes as a single flat URL rather than recognizing that when attributeName is set to href or xlink:href, the values attribute carries SMIL URI-list semantics — a semicolon-separated list of destinations. An attacker can craft a payload such as values="#safe;javascript:alert(1)" where the leading safe fragment (#safe) passes the flat scheme check, but the browser subsequently animates the link to the javascript: destination after sanitization. The fix introduces an animatesUrlAttribute() function that rejects any SVG animation element whose attributeName targets a URL sink (e.g., href, xlink:href, or any attribute listed in allowedSchemesAppliedToAttributes), discarding the entire animation element rather than attempting to parse the SMIL list (GitHub Advisory, Fix Commit). The default sanitize-html configuration is not affected, as SVG animation elements are not in the default allowedTags; only configurations that explicitly permit these elements are vulnerable.

Impact

A successful exploit allows an authenticated attacker to store a malicious SVG payload that executes arbitrary JavaScript in the application's origin when a victim clicks the sanitized link. This can lead to session hijacking, credential theft, unauthorized actions performed on behalf of the victim, and potential escalation within the application. Confidentiality and integrity are both partially impacted (low), while availability is unaffected (GitHub Advisory).

Exploitability

No public exploit kit or weaponized tooling has been reported, and there is no evidence of in-the-wild exploitation as of the disclosure date. A proof-of-concept was included in the security advisory itself, demonstrating the bypass with sanitize-html@2.17.6 and Chromium 150.0.7871.124. The vulnerability requires low privileges (authenticated user) and user interaction (victim must click the link), limiting its attack surface. The EPSS score is approximately 0.185%, and the vulnerability is not listed in the CISA KEV catalog. NVD SSVC assessment classifies exploitation as "none" (GitHub Advisory).

Exploitation steps

  1. Identify a vulnerable instance: Confirm the target application uses sanitize-html versions >= 1.9.0 and <= 2.17.6 with a configuration that explicitly allows SVG animation elements (animate, animateColor, animateMotion, animateTransform, or set) along with attributeName and value attributes (values, from, to, or by).
  2. Craft the malicious SVG payload: Construct an SVG snippet using an <animate> element with attributeName="href" and a values list that begins with a safe fragment and contains a javascript: URI, e.g.:
<svg><a><text y="20">Click me</text><animate attributeName="href" values="#safe;javascript:alert(document.origin)" dur="1s" fill="freeze"/></a></svg>
  1. Submit the payload: As an authenticated user, inject the crafted SVG into any content field that is processed by the vulnerable sanitize-html configuration (e.g., a rich-text editor or content block that allows SVG).
  2. Bypass sanitization: The sanitizer validates values as a flat URL; the leading #safe fragment passes the scheme check, and the full semicolon-separated list (including javascript:alert(...)) is retained in the sanitized output.
  3. Trigger execution: When a victim views the page and clicks the rendered SVG link, the browser animates the href attribute to the javascript: destination and executes the script in the application's origin, achieving stored XSS (GitHub Advisory, Fix Commit).

Indicators of compromise

  • Logs: HTTP requests containing SVG content with animate, animateColor, animateMotion, animateTransform, or set elements alongside attributeName values of href or xlink:href in POST bodies to content submission endpoints; presence of semicolon-delimited values attributes containing javascript: in stored content or request logs.
  • File System / Database: Stored content records containing SVG animation elements with attributeName="href" and values attributes that include javascript: URIs or other executable schemes.
  • Network: Unexpected outbound requests from victim browsers to attacker-controlled domains following interaction with SVG content; JavaScript-initiated data exfiltration (e.g., document.cookie sent via fetch or XMLHttpRequest) originating from the application's origin.
  • Browser / Client-Side: Unexpected JavaScript execution (e.g., alert dialogs, console errors, or network requests) triggered by clicking SVG links within the application.

Mitigation and workarounds

Upgrade sanitize-html to version 2.17.7 or later, which introduces the animatesUrlAttribute() check that discards any SVG animation element targeting a URL-bearing attribute (href, xlink:href, or any attribute in allowedSchemesAppliedToAttributes) (GitHub Advisory, CHANGELOG). As an immediate workaround for those unable to upgrade, remove animate, animateColor, animateMotion, animateTransform, and set from allowedTags in your sanitize-html configuration — the default configuration is not affected. Note that the apostrophecms package itself was not affected by this vulnerability; only custom configurations that explicitly permit SVG animation elements are at risk.

Community reactions

The vulnerability was responsibly disclosed by researcher koyokr and credited in the official advisory and changelog. The fix was merged via PR #5552 and released as part of the August 2026 stable reconciliation. No significant broader media coverage or notable public researcher commentary beyond the GitHub advisory has been identified.

Additional resources

Linux Distribution fix status

Fix availability across major Linux distributions and their releases.

RHEL / CentOS

Affected

OpenShift

openshift4/ose-console

Affected

RHEL 10

cockpit-image-builder.src

Affected

SourceThis report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-61560CRITICAL9.8
  • JavaScript logoJavaScript
  • @zereight/mcp-gitlab
NoYesSep 15, 2026
CVE-2026-61568CRITICAL9.6
  • JavaScript logoJavaScript
  • @zereight/mcp-gitlab
NoYesSep 15, 2026
CVE-2026-61559CRITICAL9.6
  • JavaScript logoJavaScript
  • @zereight/mcp-gitlab
NoYesSep 15, 2026
CVE-2026-63671HIGH8.1
  • JavaScript logoJavaScript
  • @nuxtjs/mdc
NoYesSep 16, 2026
CVE-2026-68904HIGH7
  • JavaScript logoJavaScript
  • node-opcua
NoYesSep 16, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management