Jul 7, 2026·7 min read·2 visits
Unauthenticated DOM-based XSS in Craft CMS Support Widget via untrusted GitHub API issue titles, patched in 4.17.16 and 5.9.23.
A DOM-based cross-site scripting (XSS) vulnerability exists in Craft CMS versions 4.0.0-RC1 through 4.17.15 and 5.0.0-RC1 through 5.9.22. The flaw resides within the CraftSupport widget's feedback search component, which fails to neutralize GitHub issue titles before rendering them into the administrator's control panel. An unauthenticated attacker can exploit this vulnerability by submitting a crafted issue to the public Craft CMS repository on GitHub.
Craft CMS incorporates an administrative control panel that provides content managers and system administrators with tools to manage web assets, users, and system configurations. To facilitate customer support and troubleshooting, the platform includes a default dashboard component called the CraftSupport widget. This widget allows administrators to search for public issues, submit feedback, and review error logs directly from their active control panel interface.
The search functionality exposes an external attack surface by interacting directly with the public GitHub API. When an administrator initiates a search within the 'Give feedback' screen, the widget queries the public repository 'craftcms/cms' on GitHub. Because the widget processes external, third-party data dynamically on the client side, it introduces a trust boundary issue between the local administrative session and remote public content.
The core vulnerability is classified as a DOM-based Cross-Site Scripting (XSS) flaw under CWE-79. Because the application does not properly sanitize the retrieved issue titles before appending them to the Document Object Model (DOM), arbitrary markup within those titles executes immediately. This allows any unauthenticated actor capable of creating a GitHub issue to inject and execute malicious scripts in the security context of the authenticated administrator.
The technical flaw lies in the handling of JSON payloads returned from the GitHub Search API by the client-side JavaScript of the CraftSupport widget. Specifically, the widget utilizes the endpoint 'https://api.github.com/search/issues' to locate relevant issues in the 'craftcms/cms' repository. The returned payload contains an array of issue objects, each containing metadata such as the issue title, status, and URL.
The client-side controller, implemented in 'src/web/assets/craftsupport/src/CraftSupportWidget.js', parses these results and dynamically constructs the HTML structure to display them. To extract the text for display, the application invokes the helper method 'this.getSearchResultText(results[i])', which directly returns the unescaped issue title from the GitHub JSON payload. Rather than treating this string as raw text, the script passes it directly to jQuery functions that manipulate the DOM.
In the vulnerable implementation, the unescaped title is concatenated with structural HTML tags and passed to the jQuery 'html' property within an anchor tag initialization. Because jQuery processes the 'html' property by setting the 'innerHTML' of the element, the browser's HTML parser interprets any embedded markup. An attacker needs only a valid GitHub account to submit a public issue containing JavaScript payloads to the official repository, which then serves as the persistent delivery mechanism.
A secondary injection vector exists within the error rendering path of the 'parseSupportResponse' method. When rendering server-side error responses, the code loops through the returned errors and dynamically appends them using raw string concatenation inside '($('<li>' + error + '</li>'))'. Since the error parameter is treated as HTML rather than plain text, any malicious content within the error payload is similarly parsed and executed in the client's browser context.
To understand the vulnerability, we analyze the raw source code of 'src/web/assets/craftsupport/src/CraftSupportWidget.js' prior to the patch. The following code block demonstrates how the unescaped issue title was rendered directly as HTML:
// Vulnerable Implementation in CraftSupportWidget.js
this.$searchResults.append(
$('<li>').append(
$('<a>', {
href: this.getSearchResultUrl(results[i]),
target: '_blank',
html:
'<span class="status ' +
this.getSearchResultStatus(results[i]) +
'"></span>' +
this.getSearchResultText(results[i]), // Vulnerable: Raw HTML assignment
})
)
);In the snippet above, the 'html' key in the jQuery configuration object instructs the library to assign the concatenated string directly to the target element's 'innerHTML' property. If the value returned by 'this.getSearchResultText(results[i])' contains malicious HTML elements, they are executed immediately. The application makes no attempt to sanitize or escape HTML special characters before this assignment.
The official fix, implemented in commit '6bbb66038a268552180ca5c8eed9f46ea25a4417', introduces a neutralization step using a native sanitization routine. The following code block shows the changes introduced by the development team:
// Patched Implementation in CraftSupportWidget.js
this.$searchResults.append(
$('<li>').append(
$('<a>', {
href: this.getSearchResultUrl(results[i]),
target: '_blank',
html:
'<span class="status ' +
this.getSearchResultStatus(results[i]) +
'"></span>' +
Craft.escapeHtml(this.getSearchResultText(results[i])), // Resolved: Escapes special characters
})
)
);The implementation of 'Craft.escapeHtml()' converts characters like '<', '>', '&', '"', and ''' into their corresponding HTML entity representations. Consequently, the browser renders the markup as inert text instead of parsing it as executable code. Furthermore, the error-rendering routine was refactored to use the jQuery text initialization parameter, which leverages browser text safe assignment methods underneath to ensure protection.
Exploitation of this DOM-based XSS vulnerability follows a multi-stage process that leverages GitHub as an untrusted intermediary. The attack requires no prior authentication or access to the target Craft CMS instance. The adversary must first identify a standard, public GitHub account and use it to register an issue in the official 'craftcms/cms' repository.
The attacker crafts an issue title designed to exploit the DOM rendering logic. A typical payload utilizes standard HTML injection vectors, such as an image tag with an invalid source attribute and an active event handler: Malfunction in Postgres database <img src="x" onerror="alert(document.cookie)">. The attacker submits this issue, and the GitHub API indexes it immediately under the keyword.
The execution phase occurs when an administrator logged into the vulnerable Craft CMS instance accesses the control panel and navigates to the CraftSupport widget. If the administrator enters a search term that matches the attacker's public issue, the widget queries the GitHub API. The API returns the JSON payload containing the poisoned title, which is then processed on the administrator's local browser.
Because the administrator is authenticated within the control panel, the injected script executes with high privileges. The attacker's script can interact with the Craft CMS API to perform unauthorized actions. This includes uploading malicious plugins, modifying system configurations, creating new administrative accounts, or exfiltrating session tokens.
The severity of CVE-2026-55790 is rated as High, with an official CVSS v4.0 base score of 7.4. The attack vector is Network, and the attack complexity is Low, meaning it can be executed reliably. Although it requires a prerequisite and user interaction from the administrator, the privileges required are None for the initial attacker.
The compromise of an administrative session in Craft CMS leads to complete loss of confidentiality and integrity on the affected system. Because the administrator possesses full control over the application environment, any JavaScript executed in their context can invoke administrative actions. This bypasses standard access controls and allows the execution of arbitrary server-side code through the platform's native development utilities.
For instance, the script can issue background AJAX requests to the plugin installation endpoints or the system console. This effectively turns a client-side DOM XSS into a remote code execution vector on the server hosting Craft CMS. Given that many Craft CMS installations manage critical e-commerce database tables or sensitive customer profiles, the exposure of these systems presents substantial organizational risks.
The primary and recommended remediation strategy is to upgrade all vulnerable Craft CMS installations to patched releases. For organizations utilizing Craft CMS v4.x, the platform must be updated to version 4.17.16 or higher. For organizations utilizing Craft CMS v5.x, the system must be updated to version 5.9.23 or higher. These updates contain the commit '6bbb66038a268552180ca5c8eed9f46ea25a4417' which implements proper HTML escaping.
In environments where an immediate upgrade is not feasible, administrators should disable or remove the CraftSupport widget from all dashboards. This can be achieved by removing the widget component from the control panel dashboard configuration or modifying user permissions to prevent access to the support interface. Disabling the widget completely removes the vulnerable client-side code path from the execution flow.
To provide defense-in-depth, security teams should implement a strict Content Security Policy (CSP) for the administrative control panel. The CSP should explicitly disallow the unsafe-inline directive for scripts and restrict executable sources to trusted domains. Furthermore, egress filtering should be configured on the host server to limit the capability of the CMS to communicate with unexpected external domains.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS v4.0 Score | 7.4 (High) |
| EPSS Score | 0.00311 (Percentile: 22.91%) |
| Impact | Administrative Session Hijacking / Remote Code Execution |
| Exploit Status | PoC / None detected in wild |
| CISA KEV Status | Not Listed |
An access control deficiency in the 9Router dashboard allows unauthenticated remote attackers to perform full CRUD operations on integrated AI providers, extract plaintext API keys, and access complete system conversation histories.
CVE-2026-55793 is a DOM-based Stored Cross-Site Scripting (XSS) vulnerability affecting Craft CMS versions 5.0.0-RC1 through 5.9.22. An authenticated user with minimum Author privileges can store a malicious payload in an entry's title. When an administrator or high-privileged user performs a drag-and-drop operation under the modified entry in the structure table view, the unescaped payload is retrieved and concatenated into raw HTML, resulting in arbitrary JavaScript execution within the context of the administrative session.
Craft CMS versions 5.9.0 through 5.9.9 are vulnerable to authenticated Remote Code Execution (RCE). An attacker with control panel permissions to edit entries can inject malicious Twig templates into the client-side HTTP Referer header. During the post-save redirect sequence, the server evaluates this user-controlled header using an unsandboxed Twig rendering function, leading to arbitrary system command execution.
An authenticated SQL injection vulnerability exists in the datapoint crosstab export functionality of OpenRemote. The vulnerability is caused by insecure manual SQL string construction that concatenates user-controlled display data, specifically asset display names and attribute names, directly into raw SQL statements. These statements are processed by the PostgreSQL database engine using the crosstab function to structure dynamic CSV outputs.
An insecure redirect vulnerability in Coder allows an authenticated attacker who controls a workspace agent to perform unauthorized cross-agent file operations and achieve remote code execution in other workspaces. By exploiting default redirect-following behavior in the control-plane's HTTP client, a malicious agent can redirect legitimate requests to a victim's deterministic tailnet IP address.
CVE-2026-35341 is a high-severity vulnerability in the mkfifo utility of uutils coreutils, involving a logic-flow bypass and a TOCTOU race condition that permits unauthorized file permission degradation and privilege escalation.