XPath Injection in .NET XML Queries

High Risk Injection
csharpdotnetxpathinjectionxmlauthentication

What it is

XPath injection vulnerabilities occur when user-controlled strings are concatenated into XPath expressions without validation or escaping. This allows attackers to manipulate XML queries to bypass authentication, access unauthorized data, or extract sensitive information from XML documents.

using System.Xml;

public bool AuthenticateUser(string username, string password)
{
    XmlDocument doc = new XmlDocument();
    doc.Load("users.xml");
    
    // VULNERABLE: direct concatenation allows XPath injection
    string xpath = $"//user[username='{username}' and password='{password}']";
    XmlNode userNode = doc.SelectSingleNode(xpath);
    
    return userNode != null;
}

// Attack: username = "admin' or '1'='1" password = "anything"
// Result: //user[username='admin' or '1'='1' and password='anything']
// This bypasses authentication by always evaluating to true
using System.Xml;
using System.Text.RegularExpressions;
using System.Linq;

public bool AuthenticateUser(string username, string password)
{
    // Validate input format
    if (!IsValidUsername(username) || string.IsNullOrEmpty(password))
    {
        return false;
    }
    
    XmlDocument doc = new XmlDocument();
    doc.Load("users.xml");
    
    // SECURE: Use DOM traversal instead of XPath
    foreach (XmlNode userNode in doc.SelectNodes("//user"))
    {
        string nodeUsername = userNode["username"]?.InnerText;
        string nodePassword = userNode["password"]?.InnerText;
        
        if (nodeUsername == username && 
            VerifyPassword(password, nodePassword))
        {
            return true;
        }
    }
    return false;
}

private bool IsValidUsername(string username)
{
    return !string.IsNullOrEmpty(username) && 
           Regex.IsMatch(username, @"^[a-zA-Z0-9._-]+$") && 
           username.Length <= 50;
}

private bool VerifyPassword(string plaintext, string hashed)
{
    return BCrypt.Net.BCrypt.Verify(plaintext, hashed);
}

💡 Why This Fix Works

The vulnerable code concatenates user input directly into XPath expressions, allowing attackers to inject malicious XPath to bypass authentication. The secure version validates input format and uses safe DOM traversal with iteration instead of dynamic XPath queries.

Why it happens

Using string concatenation or interpolation to build XPath expressions with user input.

Root causes

Direct String Concatenation in XPath

Using string concatenation or interpolation to build XPath expressions with user input.

Missing XPath Character Escaping

Not escaping special XPath characters like single quotes in user input.

Dynamic XPath Query Construction

Building XPath queries dynamically based on user input without validation.

Fixes

1

Use DOM Traversal Instead

Replace XPath queries with safe DOM traversal using SelectNodes and iteration.

2

Use LINQ to XML

Use LINQ to XML for safer querying with strongly-typed access.

3

Validate Input Format

Use allowlist validation to ensure user input matches expected format before XML operations.

Detect This Vulnerability in Your Code

Sourcery automatically identifies xpath injection in .net xml queries and many other security issues in your codebase.