CWE-91: XML Injection
Overview
This guidance helps interpret DAST findings for CWE-91: XML Injection. During dynamic scanning, the scanner detected that XML structure could be manipulated by injecting XML syntax into user-controlled data fields, altering the parsed document structure.
What the DAST scanner detected:
- XML metacharacters (
<,>,</tag>,<!--,<![CDATA[) in input parameters reflected unescaped in XML responses - Modified XML structure observable in responses (e.g., injected
<admin>true</admin>tags appear in parsed output) - XML parsing errors or malformed structures when injection payloads are submitted
- Application logic changes based on injected XML elements (e.g., privilege escalation via injected
<role>admin</role>) - Different behavior when XML-valid vs XML-invalid input is provided
Key DAST evidence:
- Input:
name=John</name><role>admin</role><name>Doeresults in parsed XML containing unexpected<role>admin</role>element - Response XML shows injected elements:
<user><name>Alice</name><isAdmin>true</isAdmin><!--- injected --></user> - Application grants unauthorized access after XML structure manipulation
- Error:
XML Parsing Error: mismatched tag. Expected: </user>when invalid XML submitted - CDATA injection:
name=Bob]]><admin>true</admin><![CDATA[xbreaks out of CDATA section
Note: CWE-91 (XML Injection) involves modifying XML structure. External entity expansion and DTD processing are covered under CWE-611 (XXE).
Analyzing the Dynamic Scan Result
What the DAST Scanner Found
When reviewing your security scan results, you'll see:
HTTP Request Details
- URL and endpoint that triggered the finding
- HTTP method (GET, POST, etc.)
- Query parameters or form data with test payloads
- Request headers and body content
HTTP Response Evidence
- Response showing the vulnerability manifestation
- Evidence of improper handling or injection
- Runtime behavior indicators
Attack Vector
- Which parameter or input is vulnerable
- Type of exploitation possible
- Context where the vulnerability appears
Mapping DAST Findings to Source Code
Find the Vulnerable Endpoint
Use the HTTP request URL to locate the code:
# Search for the URL path in your codebase
grep -r "/api/xml" src/
grep -r "/export" src/
grep -r "/generate" src/
grep -r "/rss" src/
grep -r "route.*export" src/
Locate the Route Handler
Common patterns to search for:
- Python Flask/Django:
@app.route('/export'),path('api/xml/', ...) - Node.js Express:
app.post('/generate', ...),router.get('/rss', ...) - Java Spring:
@PostMapping("/export"),@GetMapping("/api/xml") - ASP.NET:
[Route("export")],[HttpPost("generate")] - PHP:
$_POST['name'], XML generation from user input
Find the Parameter Handling
Search for the vulnerable parameter name:
# Find where the parameter is accessed
grep -r "request.form.get('name')" src/ # Python Flask
grep -r "req.body.title" src/ # Node.js
grep -r "@RequestParam.*name" src/ # Java Spring
grep -r "Request.Form['description']" src/ # ASP.NET
grep -r "$_POST['content']" src/ # PHP
Trace to Vulnerable Operation
Look for where the parameter is used in:
- XML construction: String concatenation to build XML
- Template rendering: XML templates with user data
- SOAP message generation: Building SOAP envelopes
- RSS/Atom feed generation: User content in XML feeds
- XML serialization: Converting objects to XML with user-controlled fields
Remediation
Core principle: Never construct XML by concatenating untrusted input; use XML libraries that treat user input as data and automatically escape it so it cannot alter document structure.
→ For comprehensive remediation guidance, see Static CWE-91 Guidance
Language-Specific Guidance
The static guidance provides detailed remediation steps for many languages. If you need language-specific examples:
Verification and Follow-Up Testing
After applying the fix:
Reproduce the Vulnerability
# Use curl to test XML injection
curl -X POST "http://localhost:3000/export" \
-d "name=John</name><role>admin</role><name>Doe"
curl -X POST "http://localhost:3000/generate" \
-d "title=Test</title><admin>true</admin><title>Article"
# Or use browser DevTools Network tab to copy as cURL
XML Injection Payloads:
# Tag injection
John</name><admin>true</admin><name>Doe
# Comment injection
value--><admin>true</admin><!--
# CDATA injection
]]><admin>true</admin><![CDATA[
# Attribute injection
" role="admin
Verify the Fix
- Confirm no XML is built via string concatenation
- Confirm user input is passed as data nodes / attributes via XML APIs
- Confirm XML serializers perform automatic escaping
- Confirm attackers cannot inject tags, attributes, namespaces, or CDATA
- Confirm malformed XML does not leak parser errors
Test Edge Cases
# Tag closure injection
/export?name=</name><role>admin</role><name>
# Multiple field injection
/generate?title=Test&author=</author><isPublic>true</isPublic><author>
# Namespace injection
/api/xml?data=</item><item xmlns:evil="http://evil.com">
# Or use browser DevTools Network tab to copy as cURL
Re-run DAST Scanner
Run your dynamic scanner again on the fixed endpoint to confirm remediation.