Security

What is XML Injection (CWE-91)?

XML Injection (CWE-91) lets attackers manipulate XML structure and XPath queries. See real vulnerable/secure code and the parameterization fix.

SP
Shreya Pillai July 27, 2026 6 min read Security
AI-friendly summary

What it is: XML Injection (aka Blind XPath Injection) (CWE-91) is a type of injection vulnerability where an application does not neutralize special characters used in XML or XPath syntax before incorporating untrusted input.

Why it matters: An attacker can alter an XML document's structure or manipulate an XPath query's logic — including bypassing authentication checks built on XPath queries against an XML user store.

How to fix it: Use XML-library escaping functions for data written into documents, and parameterized XPath queries via variable binding instead of string concatenation.

TL;DR: XML Injection lets an attacker manipulate XML document structure or XPath query logic via unescaped input; the fix is XML-library escaping for documents and parameterized XPath variable binding for queries.

Field Value
CWE ID CWE-91
OWASP Category A05:2025 - Injection
CAPEC CAPEC-250, CAPEC-83
Typical Severity High
Affected Technologies Applications processing XML input or using XPath queries
Detection Difficulty Moderate
Last Updated 2026-07-27

What is XML Injection?

XML Injection (aka Blind XPath Injection) (CWE-91) is a type of injection vulnerability that occurs when a product does not properly neutralize special elements used in XML, allowing attackers to modify the syntax, content, or commands of the XML before it is processed by an end system. As defined by the MITRE Corporation under CWE-91, and classified by the OWASP Foundation under A05:2025 - Injection, this weakness is a direct child of the broader Special Element Injection weakness family (CWE-74).

Quick Summary

This weakness covers two closely related attacks against XML-based systems: injecting new elements/attributes into a raw XML document being constructed from user input, and manipulating an XPath query’s logic the same way SQL Injection manipulates a SQL query — often “blind,” since the attacker infers success from application behavior differences rather than seeing the raw XPath result directly.

Jump to: Quick Summary · XML Injection Overview · How XML Injection Works · Business Impact of XML Injection · XML Injection Attack Scenario · How to Detect XML Injection · How to Fix XML Injection · Framework-Specific Fixes for XML Injection · How to Ask AI to Check Your Code for XML Injection · XML Injection Best Practices Checklist · XML Injection FAQ · Vulnerabilities Related to XML Injection · References · Scan Your Own Site

XML Injection Overview

What: User input is concatenated into an XML document or XPath query string without neutralizing XML/XPath-meaningful characters.

Why it matters: An attacker can alter a document’s structure or an XPath query’s logic, including bypassing authentication checks built against XML-stored credentials.

Where it occurs: Features that build XML documents or XPath queries from user input via string concatenation.

Who is affected: Applications using XML-based data stores or configuration with XPath queries built from unescaped user input.

Who is NOT affected: Applications using XML-library escaping for document content and parameterized XPath queries via variable binding.

How XML Injection Works

Root Cause

The application concatenates untrusted input directly into an XML document or XPath query string without neutralizing special characters meaningful to XML/XPath syntax.

Attack Flow

  1. The attacker identifies a feature that builds an XML document or XPath query using user input (e.g. an XML-backed login check).
  2. The attacker submits a value containing XPath syntax, e.g. ' or '1'='1.
  3. The application concatenates this directly into the XPath expression.
  4. The XPath engine evaluates the injected logic as part of the query, matching records it shouldn’t.
  5. The attacker bypasses the intended check (e.g. authentication) or extracts data via blind boolean inference.

Prerequisites to Exploit

  • User input reaches an XML document or XPath query construction step without escaping.
  • The application concatenates that input directly into the document/query string.
  • The XPath query (if applicable) is used for a security-relevant decision, like authentication.

Vulnerable Code

from lxml import etree

def check_login(username, password, xml_doc):
    query = f"//user[username/text()='{username}' and password/text()='{password}']"
    return xml_doc.xpath(query)

Both username and password are concatenated directly into the XPath expression, so a username value of ' or '1'='1 matches every user record, bypassing the credential check entirely.

Secure Code

from lxml import etree

def check_login(username, password, xml_doc):
    query = "//user[username/text()=$u and password/text()=$p]"
    return xml_doc.xpath(query, u=username, p=password)

Binding username and password as XPath variables keeps them as literal data values, so the query’s logic can’t be altered no matter what characters they contain.

Business Impact of XML Injection

Confidentiality: Attackers may extract data from an XML store through blind boolean-based inference techniques, similar to blind SQL injection.

Integrity: Attackers may inject additional elements or attributes into a constructed XML document, corrupting its intended structure.

Authentication: Attackers may bypass authentication checks built on XPath queries against an XML-based credential store.

  • Full bypass of authentication logic built on vulnerable XPath queries
  • Data exposure from an XML store via slow, blind extraction techniques

XML Injection Attack Scenario

  1. An attacker finds a legacy application that authenticates users against an XML file using XPath queries.
  2. They submit ' or '1'='1 as the username with any password.
  3. The resulting XPath expression matches every <user> element in the document, regardless of credentials.
  4. The application logs the attacker in as the first matched user, often an administrator record listed first in the file.

How to Detect XML Injection

Manual Testing

  • Identify features that build XML documents or XPath queries from user input.
  • Submit XML-meaningful characters (<, >, &, ', ") and XPath boolean payloads.
  • Confirm whether application behavior changes in ways consistent with injected structure or logic.

Automated Scanners (SAST / DAST)

Static analysis can flag XML/XPath strings built via concatenation with variables directly in source, while dynamic testing with boolean-based payloads confirms whether the live application’s XPath evaluation is actually affected.

PenScan Detection

PenScan’s scanner engines test inputs that reach XML construction or XPath queries with structural and boolean-based injection payloads.

False Positive Guidance

An input reaching XML/XPath processing only through library-provided escaping or variable-binding APIs is not vulnerable even if it superficially resembles an injectable sink — confirm the actual construction method used before treating it as a real finding.

How to Fix XML Injection

  • Use XML-library-provided escaping functions for any data written into an XML document.
  • Use parameterized XPath queries via variable binding instead of string concatenation.
  • Validate input against expected formats as defense-in-depth alongside proper escaping/parameterization.

Framework-Specific Fixes for XML Injection

  • Java: use XPath.setXPathVariableResolver() for parameterized XPath queries, and javax.xml.transform escaping utilities for document content.
  • Python: use lxml’s XPath variable binding (xpath(query, **vars)), as shown above, and xml.sax.saxutils.escape() for document content.
  • Node.js: use a library that supports parameterized XPath (e.g. xpath with variable resolvers), and escape document content with a maintained XML library.
  • PHP: use DOMXPath::evaluate() with pre-validated, type-checked values rather than string concatenation, and htmlspecialchars()-equivalent XML escaping for document content.

How to Ask AI to Check Your Code for XML Injection

Copy-paste prompt

Review the following [language] code block for potential CWE-91 XML Injection / Blind XPath Injection vulnerabilities and rewrite it using parameterized XPath variable binding and proper XML escaping: [paste code here]

XML Injection Best Practices Checklist

✅ Use XML-library escaping functions for all data written into documents ✅ Use parameterized XPath queries via variable binding, never string concatenation ✅ Never build authentication logic on unparameterized XPath queries ✅ Validate input formats as defense-in-depth alongside proper escaping

XML Injection FAQ

How does XML Injection let an attacker manipulate an XML document?

If user input is concatenated directly into an XML string without escaping characters like “<” and “&”, an attacker can inject new elements or attributes, changing the document’s structure in ways the application never intended.

How does Blind XPath Injection differ from XML Injection?

XML Injection manipulates the raw XML document structure itself; Blind XPath Injection instead manipulates an XPath query string used to search that XML, similar in spirit to SQL Injection but against XPath’s query syntax, and is “blind” because the attacker typically infers results from application behavior rather than seeing raw output.

How can an attacker use Blind XPath Injection to bypass authentication?

If an XPath query like //user[username/text()='{input}' and password/text()='{input}'] is built with unescaped input, a value like ' or '1'='1 changes the query to match every user record, bypassing the credential check entirely.

How do I detect this in my own application?

Identify any feature that builds XML or XPath queries from user input, and test with XML-meaningful characters (<, >, &, ‘, “) or XPath boolean payloads to see whether the application’s behavior changes.

How do I fix this correctly?

Use XML-library-provided escaping functions for any data written into an XML document, and use parameterized XPath queries (via XPath variable binding) instead of string concatenation.

How does XPath variable binding work like a SQL prepared statement?

Most XPath libraries support binding named variables into a compiled expression, so user-supplied values are passed as data rather than parsed as part of the XPath syntax itself — structurally the same protection a SQL prepared statement provides.

How can PenScan help find XML Injection?

PenScan tests inputs that reach XML construction or XPath queries with structural and boolean-based injection payloads to confirm whether the application is vulnerable.

CWE Name Relationship
CWE-74 Improper Neutralization of Special Elements in Output Used by a Downstream Component (‘Injection’) ChildOf

References

Scan Your Own Site

Manual code review catches what you know to look for. An automated scan catches what you didn’t. Scan your own website using PenScan to find XML Injection and other risks before an attacker does.