TL;DR
An XML External Entity (XXE) vulnerability in your ASP.NET SOAP service lets attackers read files on your server or interact with internal systems. This guide shows you how to disable XML processing features that cause the problem, and how to validate input if disabling isn’t possible.
Understanding the Problem
SOAP services use XML for messages. If your ASP.NET code parses XML without proper safeguards, an attacker can include malicious entities in their SOAP request. These entities can:
- Read local files: Access sensitive data like configuration files or passwords.
- Internal scans: Discover internal network resources.
- Denial of Service (DoS): Crash your server with large XML documents.
Solution Steps
- Disable XXE Features in web.config (Recommended)
The easiest and most effective way to prevent XXE is to disable the features that allow it. Edit your
web.configfile.- Locate the <system.xml> section.
- Add the following settings:
<system.xml> <readersSettings processingTimeout="10s" maxDocumentSize="2048" processingMode="Separate" ignoreComments="true" ignoreWhitespace="true" ignoreUnknownCharacters="true" /> </system.xml>Explanation:
processingTimeout: Limits the time spent processing XML.maxDocumentSize: Restricts the size of incoming XML documents.processingMode="Separate": Processes XML in a separate thread, reducing impact if an attack occurs.ignoreComments="true",ignoreWhitespace="true",ignoreUnknownCharacters="true": Helps prevent entity injection by ignoring potentially malicious content.
- Disable DTD Processing
DTDs (Document Type Definitions) are a common source of XXE vulnerabilities. Disable them.
- Add this to your
web.configwithin the <system.xml> section:
<xmlReaderSettings DtdProcessing="Prohibit" />Explanation:
DtdProcessing="Prohibit"prevents the XML parser from loading external DTDs. - Add this to your
- Disable External Entity Resolution
This is another crucial step to block XXE attacks. Add this setting in
web.config:- Add this within the <system.xml> section:
<xmlReaderSettings XmlResolver="null" />Explanation:
XmlResolver="null"prevents the XML parser from resolving external entities. - Input Validation (If Disabling is Not Possible)
If you absolutely *must* allow some XML processing, validate all input carefully. This is harder and less reliable than disabling features.
- Whitelist allowed schemas: Only accept XML documents that conform to a specific schema you control.
- Sanitize Input: Remove or encode potentially dangerous characters before parsing the XML. Be very careful with this – it’s easy to miss something.
- Limit Entity Expansion: Control the maximum number of entity expansions allowed during parsing.
- Code Example (C# – Input Validation)
This is a *basic* example and should be adapted to your specific needs.
using System.Xml; public XmlDocument LoadAndValidateXML(string xmlString) { XmlDocument doc = new XmlDocument(); try { doc.LoadXml(xmlString); // Add validation logic here to check against your allowed schema. // For example, check the root element name: if (doc.DocumentElement.Name != "MyExpectedRoot") { throw new Exception("Invalid XML format"); } } catch (Exception ex) { throw new Exception("Error parsing or validating XML: " + ex.Message); } return doc; } - Testing
After making changes, test your SOAP service thoroughly.
- Use a tool like Burp Suite or OWASP ZAP to send malicious XML payloads and verify that the attacks are blocked.
- Try reading local files (e.g.,
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [&entity_name; "file:///etc/passwd"]>&entity_name;) to confirm XXE is prevented.
Important Considerations
- Regular Updates: Keep your ASP.NET framework and libraries up-to-date with the latest security patches.
- Least Privilege: Run your application with the minimum necessary permissions to reduce the impact of a successful attack.