Read-Only Primitives
document() and system-property() work on effectively every XSLT processor, no extensions required. File read, SSRF, and fingerprinting.RCE Extensions
EXSLT, PHP’s
xsl extension, Xalan (Java), and msxsl:script (.NET) each expose their own path to file write or direct code execution, but only when that specific extension is enabled.Fingerprinting the Processor
Before trying any RCE payload, find out which XSLT engine and version you’re dealing with, each vendor supports a different set of extensions.system-property() is part of the XSLT 1.0 spec and works everywhere.
File Read and SSRF via document()
document() is meant to pull in a second XML source during a transform, nothing stops it from being pointed at a local file path or a URL instead. It works without any extension enabled, making it the first thing worth trying once injection is confirmed.
File Write via EXSLT
The EXSLTcommon extension (exsl:document on some processors, exploit:document with any arbitrary namespace alias here) writes the transform’s output to a new file on disk instead of just returning it, turning an injection point into an arbitrary file write.
Swap the literal text for a webshell payload and
evil.txt for a web-accessible path with an executable extension, and this becomes direct RCE without needing any of the extensions below. Whether it works depends entirely on whether the host’s XSLT processor has EXSLT support compiled in.RCE by Processor
- PHP (libxslt)
- Java (Xalan)
- .NET (MSXML / XslCompiledTransform)
PHP’s The same mechanism reads files, lists directories, or drops a webshell to disk, all without needing EXSLT at all.
XSLTProcessor ships with its own php:function extension that lets a stylesheet call arbitrary PHP functions directly by name, this is by far the most reliable RCE path when the vendor fingerprint comes back as libxslt.Don’t Forget XXE
An XSLT document is itself XML, so anywhere a stylesheet is accepted, the surrounding document is also a candidate for a classicDOCTYPE/ENTITY injection, independent of anything XSLT-specific. If the RCE/file-read paths above are not working, drop back to testing standard XXE against the stylesheet file itself (see XXE for the full technique set).
Quick Reference Tools
PayloadsAllTheThings: XSLT Injection
Reference used for this page.

