XPath Injection in .NET XML Queries

High Risk Injection
csharpdotnetxpathinjectionxml

What it is

XPath injection vulnerabilities occur when user-controlled strings are concatenated into XPath expressions without proper validation or escaping. This allows attackers to manipulate XML query logic 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
using System.Xml;
using System.Text.RegularExpressions;

public bool AuthenticateUser(string username, string password)
{
    // Validate input
    if (!IsValidUsername(username) || string.IsNullOrEmpty(password))
    {
        return false;
    }
    
    XmlDocument doc = new XmlDocument();
    doc.Load("users.xml");
    
    // SECURE: Use DOM traversal instead of dynamic 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 construction.

Why it happens

Building XPath expressions with string interpolation or concatenation using user input.

Root causes

String Concatenation in XPath

Building XPath expressions with string interpolation or concatenation using user input.

Missing XPath Escaping

Not escaping single quotes and other special XPath characters in user input.

Dynamic XPath Construction

Building XPath queries dynamically based on untrusted user input.

Fixes

1

Use DOM Traversal

Replace dynamic XPath 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.

Detect This Vulnerability in Your Code

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