Aug 28, 2026·6 min read·2 visits
A design shortcut in Silverstripe Framework's iframe sandboxing allows attackers to bypass security filters using simple single-tag iframe embeds, enabling unauthenticated or lower-privileged administrative session takeover.
CVE-2026-54720 is a stored Cross-Site Scripting (XSS) vulnerability inside the Silverstripe Framework's media shortcode processor. Due to a flawed performance optimization, HTML inputs containing two or fewer opening angle brackets bypassed security sandboxing. This flaw allows authenticated or lower-privileged users to inject administrative panel payloads that execute arbitrary client-side JavaScript when viewed by system administrators.
The Silverstripe Framework incorporates a rich-text editing system within its content management panel that supports embedding third-party media. This capability is managed via shortcodes parsed on the server side before rendering. The core mechanism is implemented in the EmbedShortcodeProvider class under src/View/Shortcodes/. To mitigate the risks of executing arbitrary third-party code in the hosting domain, the framework routes content through a sandboxing system.
Historically, this sandboxing system, executed via sandboxHtml(), forced potentially risky HTML embeds into isolated, sandboxed subdocuments or sandboxed iframes. However, the parser logic contained a shortcut design flaw. It assumed that basic or brief HTML segments, particularly those with small numbers of opening tags, were structurally simple enough to render directly in the parent context without risk.
This design shortcut introduced a stored Cross-Site Scripting (XSS) vulnerability classified as CWE-79. Under specific conditions, an editor or a lower-privileged user capable of injecting media shortcodes could execute arbitrary JavaScript inside the parent document context. This execution occurs when an administrative user views the page within the CMS back-end administration panel, exposing the administrator's active session to compromise.
The core vulnerability lies within the static optimization shortcut implemented in the sandboxHtml() method of EmbedShortcodeProvider.php. To optimize performance and reduce DOM nesting, the framework checked the frequency of the opening angle bracket (<) in the input HTML string. If the count of < characters was two or fewer, the code bypassed the sandboxing flow and returned the HTML string directly.
This check relied on the assumption that an HTML string containing two or fewer < characters could only represent a single tag paired with its closing tag, or two standalone safe tags. The developer assumed that a single, unsandboxed <iframe> tag was harmless because the parent context remained isolated from the inner contents. This logic overlooked the fact that the browser still processes the attributes of the container <iframe> element itself in the context of the parent document.
Because the raw iframe element is rendered inside the host page, any attribute attached to this iframe is interpreted directly by the user's browser. An attacker can append arbitrary HTML event handlers, such as onload, or inject execution protocols like javascript: or data: inside the src attribute. When the browser tokenizes the page, it executes the payload in the context of the CMS administrative panel rather than an isolated origin.
To understand the structural failure, we analyze the vulnerable logic in EmbedShortcodeProvider.php before the remediation. The system evaluated the embed input as follows:
// Vulnerable code block in version < 6.2.2
private static function sandboxHtml(string $html, array $arguments)
{
// ...
// If there's more than 2 HTML tags then sandbox it
if (substr_count($html, '<') <= 2) {
return $html;
}
// ...
}If the validation succeeded, the string $html returned unmodified. To address this, the patch introduced in version 6.2.2 routes the optimization path through a sanitization function designed to strip unsafe attributes before returning the raw HTML.
// Patched logic in version 6.2.2
if (substr_count($html, '<') <= 2) {
// Returned as-is into the main document, so strip unsafe attributes first
return EmbedShortcodeProvider::removeDangerousAttributes($html);
}This modified pathway executes removeDangerousAttributes(), which parses the iframe and retains only an explicit allowlist of layout and media attributes. The allowlist includes src, width, height, frameborder, allow, allowfullscreen, webkitallowfullscreen, mozallowfullscreen, referrerpolicy, loading, scrolling, allowtransparency, and title. It specifically strips critical layout attributes like style, script blocks like srcdoc, and event triggers like onload.
Furthermore, the helper normalizes potential obfuscation by calling html_entity_decode() and stripping non-printing control characters ([\x00-\x20]+) prior to resolving the URI scheme. This prevents attackers from bypassing simple string-matching rules with hidden white spaces or HTML character references.
Exploitation requires an attacker to inject a crafted media shortcode containing two or fewer opening angle brackets. This payload is stored in the database and triggers when an administrator views the content. There are multiple methods to execute code under these parser constraints.
First, an attacker can use a standard inline event handler. Since the iframe is parsed in the main DOM, the onload event fires automatically when the iframe element is rendered:
<iframe onload="alert(document.cookie)" src="about:blank"></iframe>Second, browsers allow spaces and alternative token separators such as the forward slash. An attacker can construct a payload that evades naive white-space parsers by using slash separators:
<iframe/onload="alert(document.cookie)" src="about:blank"></iframe>Third, execution can be forced via the src attribute. Setting the source to a pseudo-protocol like javascript: executes script inside the active origin when loaded by the DOM:
<iframe src="javascript:alert(document.cookie)"></iframe>To bypass simple signature checks, attackers can obfuscate the scheme using tab separators or HTML entities which the browser normalizes before execution:
<iframe src="java	script:alert(document.cookie)"></iframe>The practical impact of this vulnerability is significant, as represented by its CVSS 3.1 score of 5.4. While the vulnerability requires user interaction to trigger, the execution occurs within the context of an authenticated Silverstripe CMS administrator. This session exposure permits the attacker to hijack administrative control.
An attacker executing arbitrary JavaScript in the CMS admin panel can perform any action available to the victim. This includes creating new administrative user accounts, modifying existing content, altering site configuration settings, and exfiltrating sensitive data stored within the CMS.
Because the administrative panel often lacks strict anti-CSRF protections for all actions executed via API endpoints in the background, a silent background script can modify templates or download system backups. Furthermore, if administrative session cookies do not carry the HttpOnly flag, the attacker can exfiltrate active session tokens directly to an external server.
The primary remediation path is upgrading the silverstripe/framework dependency to version 6.2.2 or higher. This update introduces the sanitization logic that strips dangerous attributes and normalizes nested protocol URIs. Organizations can perform the upgrade via Composer:
composer update silverstripe/frameworkIf immediate patching is not feasible, organizations can implement virtual patching on Web Application Firewalls (WAF) to detect and block malicious shortcodes. The WAF should scan POST requests targeting content creation endpoints for suspicious iframe structures inside shortcodes. A suitable regex-based signature is:
<iframe(?:"[^"]*"|'[^']*'|[^>])*(?:onload|onmouseover|srcdoc|style)\s*=Additionally, implementing a strict Content Security Policy (CSP) can limit the impact of client-side execution. A robust CSP that restricts script execution (script-src 'self') and disallows inline scripts prevents event handlers on unsanitized elements from running, thereby neutralizing the vulnerability even if the parser bypass succeeds.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
silverstripe-framework Silverstripe Ltd. | < 6.2.2 | 6.2.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 5.4 |
| EPSS Score | 0.00263 (Percentile: 17.73%) |
| Impact | Stored XSS leading to Administrative Session Compromise |
| Exploit Status | Proof of Concept (PoC) documented |
| KEV Status | Not listed in CISA KEV Catalog |
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
An incomplete array comparison vulnerability in cakephp/queue version 0.1.11 through 2.3.0 allows unauthenticated attackers to cause key collisions in unique job deduplication. This is caused by standard array value sorting that discards associative keys, normalizing different payload keys to identical arrays and leading to a denial of service (DoS) by dropping legitimate jobs.
An input buffering vulnerability exists in the aiosmtplib asynchronous SMTP client library before version 5.1.2. When upgrading a plaintext connection to TLS via STARTTLS, the library processes buffered plaintext responses after transport negotiation has completed. This behavior allows a network-positioned attacker to inject spoofed server responses prior to negotiation, leading to command/response desynchronization, arbitrary capability injection, and potential credential theft.
An open redirect vulnerability exists in WebOb before version 1.8.11 due to a parser differential between WebOb's validation logic and Python's standard urllib.parse.urljoin() function. Under Python 3.10+, the urljoin function strips leading and trailing space characters and C0 control characters, which allowed specially crafted inputs to bypass WebOb's prefix checks while still resolving as off-host redirects.
Prior to version 1.0.0, the n8n-nodes-sqlite3 integration exposed the db_path parameter as an unrestricted node parameter. By default, n8n node parameters allow the evaluation of dynamic data expressions, meaning untrusted external input could be mapped to the database path. This vulnerability allows an external attacker to control which SQLite database file the n8n backend process attempts to open, leading to directory traversal outside of the intended directory context.
A client-side open redirect vulnerability has been identified in the Kargo user interface. The flaw resides in the handling of OpenID Connect (OIDC) login and token renewal flows, where the application extracts an unvalidated destination path from the redirectTo query parameter. Attackers can exploit this to redirect authenticated users to arbitrary external domains.
A Server-Side Template Injection (SSTI) vulnerability in the Silverstripe Advanced Workflow module allows authenticated attackers with workflow authoring permissions to achieve arbitrary code execution. By manipulating the NotifyUsersWorkflowAction.EmailTemplate field, attackers can inject template code that dynamically executes arbitrary PHP commands via the core translation helper interpolation path.