scanrub
XML Injectionlow prioritynot yet scanned

XML Injection

3 min read 3 reports analyzed ScanRub Research
Share

Summary

XML injection (CWE-91) happens when user input is inserted into an XML document without escaping the characters XML treats as structural: <, >, &, and quotes. Because those characters delimit tags, attributes, and entities, an attacker who can slip them into a value meant to be plain text can add new elements, close tags early, or redefine attributes the application never intended to expose. It's the XML equivalent of SQL injection: the vulnerability isn't in what the data says, it's in what the data is able to do once it's parsed as markup instead of text. XML External Entity injection (XXE) is the best-known and most severe outcome of this class, since a successfully injected <!ENTITY> declaration can pull in local files or make outbound requests, but XML injection also covers less severe outcomes like forging sibling elements in a SOAP request or spoofing a field the server trusts because it appears earlier in document order than the legitimate one.

◈ flow diagram
User InputLDAP Filter …Structural I…Query or Doc…Bypass or Da…

Top Affected Components / Targets

  • SOAP API endpoints that build request bodies from user-supplied fields
  • XML-based configuration or profile update endpoints
  • Any form field, header, or parameter whose value is later serialized into an XML document server-side
  • XML-RPC endpoints (WordPress xmlrpc.php and similar)

Common Attack Vectors

  • Submit a value containing an unescaped < or & and check whether it breaks the surrounding XML structure or is reflected as literal markup rather than escaped text
  • Inject a sibling closing tag (</field><injected>value</injected><field>) to terminate the intended element early and add a new one the server wasn't expecting
  • Where the application accepts raw XML directly (not just a field that gets serialized into XML), attempt a DOCTYPE declaration with an external entity to escalate into full XXE

Common Payloads

  • "><injected>test</injected><field val="
  • ]]><script> style CDATA-escape attempts, where a CDATA section is used elsewhere in the document
  • <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]><foo>&xxe;</foo> for the XXE escalation path

Detection Strategy

For any endpoint that accepts XML directly, or any field whose value is plausibly serialized into XML server-side, submit a value containing unescaped angle brackets and an ampersand, then inspect whether the server's response reflects the value as literal markup (a sign it wasn't escaped) or returns a parse error (a sign the malformed XML reached the parser unescaped, which is itself informative even without a visible injection). Where raw XML submission is accepted, layering in a DOCTYPE with an external entity tests for the more severe XXE path in the same pass, since both share the same root cause of insufficiently sanitized XML input.

Tip: Testing tools that run these checks in parallel across every discovered endpoint can cut the time required substantially compared to fully manual testing, as long as they confirm findings with more than one signal to keep the false-positive rate down.

False-Positive Notes

  • A parse error alone isn't proof of exploitability, it only shows the malformed input reached the XML parser without being escaped first; confirming real impact needs either a reflected injected element in the response or, for the XXE path, an out-of-band callback or file content appearing in the response.
  • Applications that reject malformed XML outright with a generic 400 error, without leaking parser details, are showing correct behavior, not a finding.

How to Test

Manual Testing Methodology

Here is a systematic approach to identifying XML Injection vulnerabilities in a target application.

Step 1: Reconnaissance and Surface Mapping

Before testing, map all input vectors that could be affected. Identify parameters, headers, cookies, and request bodies that interact with the vulnerable component. A proxy such as Burp Suite or OWASP ZAP, paired with normal browsing of the target, is usually enough to build this list.

Step 2: Baseline Request

Send a legitimate request and record the normal response: status code, content length, response time, and any identifying tokens. This baseline matters because it's what you'll compare later responses against once payloads are involved.

Step 3: Payload Injection

Inject test payloads into each identified input vector one at a time. Start with benign detection payloads before escalating to anything that could actually trigger the vulnerability. For XML Injection specifically, submit LDAP-filter metacharacters (*, (, ), &, |) or XML structural characters (<, >, &, a crafted closing tag) into every parameter that feeds into a directory query or an XML document, testing both authentication-bypass-style payloads and structural injection.

Step 4: Response Analysis

Compare the response against your baseline, looking specifically for authentication bypassing unexpectedly, broader directory results than the query should return, or injected elements/attributes appearing in how the application subsequently processes the document.

Step 5: Confirmation

Once a potential vulnerability is detected, confirm it with at least a few independent test cases to rule out coincidence. Document the exact request and response as proof. For XML Injection, a confirmed finding typically means showing that attacker-controlled input changes the application's behavior in a way that matters for security, not just that a payload was reflected somewhere harmless.

Real-World Impact

Real-World Impact

LDAP injection, XML injection, and related structured-syntax injection classes share the same shape as SQL injection but target a different query or document language: user input gets concatenated into an LDAP filter, an XML document, or another structured format without being escaped for that format's special characters, letting an attacker alter the structure the receiving parser sees rather than just its data.

LDAP injection specifically can let an attacker bypass authentication filters entirely (by injecting a filter that always evaluates true) or enumerate directory contents — usernames, group memberships, organizational structure — that should have required legitimate query permissions to see. XML injection can let an attacker add, modify, or spoof elements the application trusts, which is especially serious when those elements carry authorization-relevant data.

Both are less frequently reported than SQL or command injection simply because LDAP and raw XML query construction are less common than SQL in modern applications, but where they do exist, the exploitation pattern and severity are directly comparable.

Prevention & Remediation

Prevention and Secure Coding

Preventing XML Injection takes a defense-in-depth approach — no single control below is sufficient alone, but together they close off both the primary path and the most common bypasses.

Use the platform's parameterized/escaping API for the target syntax. Most LDAP and XML libraries provide a proper escaping function or parameterized filter-building API — use it instead of string concatenation, the same discipline as parameterized SQL.

Allowlist validate before it ever reaches the query. Restrict input feeding into a filter or document structure to an expected character set and length before it's used at all.

Least-privilege service accounts for the underlying directory or document store. An LDAP bind account or XML-processing service account scoped to only what it needs limits what a successful injection can actually reach.

Treat structural characters as forbidden, not something to sanitize away. Reject input containing syntax-significant characters for the target format (()&| for LDAP filters, <>& for raw XML construction) rather than trying to strip or escape them ad hoc.

Frequently Asked Questions

What is XML Injection?
XML injection (CWE-91) happens when user input is inserted into an XML document without escaping the characters XML treats as structural: `<`, `>`, `&`, and quotes.
How common is XML Injection in bug bounty reports?
Scanrub's research corpus for this playbook is built from 3 disclosed HackerOne reports in this category, synthesized for detection and prevention guidance rather than reproduced verbatim.
How do I test for XML Injection?
Map every input vector, record a baseline response, then inject targeted test payloads one field at a time and compare the response for timing, length, error, or reflection differences from that baseline. The "How to Test" section above walks through the full methodology for this specific vulnerability class.
What is the single most effective fix for XML Injection?
Build LDAP filters and XML documents through the platform's parameterized or escaping API, never by concatenating raw user input into the query/document structure.
Weekly security research

New vulnerability playbooks, tool updates, and bug bounty insights - delivered to your inbox. No spam.

Unsubscribe anytime. We respect your inbox.
Press ⌘K to search×