C# XmlDocument XXE via DTD Processing of Public Input

High Risk Injection
csharpdotnetxxexml-injectionfile-disclosuressrfdosxmldocumentsemgrep

What it is

A critical XML External Entity (XXE) vulnerability where .NET applications parse untrusted XML input using XmlDocument with DTD processing enabled. This allows attackers to read local files, perform Server-Side Request Forgery (SSRF) attacks, cause denial of service through entity expansion bombs, and potentially execute arbitrary code. XXE attacks can expose sensitive configuration files, credentials, and internal network resources.

// VULNERABLE: XmlDocument with default DTD processing
using System;
using System.Xml;
using System.IO;

public class VulnerableXmlProcessor
{
    // SECURITY ISSUE: DTD processing enabled, XmlResolver not disabled
    public static void ProcessUserXml(string xmlContent)
    {
        XmlDocument doc = new XmlDocument();
        
        // VULNERABLE: Default settings allow XXE attacks
        // DTD processing is enabled by default
        // XmlResolver allows external entity loading
        doc.LoadXml(xmlContent);
        
        // Process the document
        Console.WriteLine("Root element: " + doc.DocumentElement.Name);
    }
    
    // VULNERABLE: Loading XML from file without security
    public static XmlDocument LoadConfigFile(string filePath)
    {
        XmlDocument doc = new XmlDocument();
        
        // SECURITY ISSUE: No protection against XXE in file content
        doc.Load(filePath);
        
        return doc;
    }
    
    // VULNERABLE: Processing XML from web request
    public static void ProcessWebXml(Stream xmlStream)
    {
        XmlDocument doc = new XmlDocument();
        
        // SECURITY ISSUE: Untrusted XML from web request
        // Could contain malicious DTD and external entities
        doc.Load(xmlStream);
        
        // Extract data from XML
        XmlNodeList nodes = doc.SelectNodes("//data");
        foreach (XmlNode node in nodes)
        {
            Console.WriteLine(node.InnerText);
        }
    }
}
// SECURE: XmlDocument with XXE protection
using System;
using System.Xml;
using System.IO;

public class SecureXmlProcessor
{
    // SECURE: Disabled external entity resolution
    public static void ProcessUserXmlSecure(string xmlContent)
    {
        XmlDocument doc = new XmlDocument();
        
        // SECURE: Disable external entity resolution
        doc.XmlResolver = null;
        
        doc.LoadXml(xmlContent);
        Console.WriteLine("Root element: " + doc.DocumentElement.Name);
    }
    
    // SECURE: Loading XML with DTD protection
    public static XmlDocument LoadConfigFileSecure(string filePath)
    {
        // Use XmlReader with secure settings
        XmlReaderSettings settings = new XmlReaderSettings
        {
            DtdProcessing = DtdProcessing.Prohibit,  // Disable DTD processing
            XmlResolver = null                       // Disable external resolution
        };
        
        XmlDocument doc = new XmlDocument();
        doc.XmlResolver = null;
        
        using (XmlReader reader = XmlReader.Create(filePath, settings))
        {
            doc.Load(reader);
        }
        
        return doc;
    }
    
    // SECURE: Processing XML from web request
    public static void ProcessWebXmlSecure(Stream xmlStream)
    {
        // Secure XML processing
        XmlReaderSettings settings = new XmlReaderSettings
        {
            DtdProcessing = DtdProcessing.Prohibit,
            XmlResolver = null
        };
        
        XmlDocument doc = new XmlDocument();
        doc.XmlResolver = null;
        
        using (XmlReader xmlReader = XmlReader.Create(xmlStream, settings))
        {
            doc.Load(xmlReader);
        }
        
        // Process the secure document
        XmlNodeList nodes = doc.SelectNodes("//data");
        foreach (XmlNode node in nodes)
        {
            Console.WriteLine(node.InnerText);
        }
    }
}

💡 Why This Fix Works

The vulnerable examples show XmlDocument usage with default DTD processing that enables XXE attacks. The secure implementations disable external entity resolution, implement input validation, and use secure XmlReaderSettings to prevent XXE vulnerabilities.

Why it happens

XmlDocument in .NET Framework enables DTD processing by default, allowing external entity resolution when parsing untrusted XML. This commonly occurs when developers are unaware of the security implications of DTD processing or when using legacy XML parsing patterns that predate modern security practices.

Root causes

Default XmlDocument DTD Processing

XmlDocument in .NET Framework enables DTD processing by default, allowing external entity resolution when parsing untrusted XML. This commonly occurs when developers are unaware of the security implications of DTD processing or when using legacy XML parsing patterns that predate modern security practices.

Missing XmlResolver Nullification

Code fails to set XmlDocument.XmlResolver = null to disable external entity resolution. This happens when developers don't understand that the XmlResolver is responsible for loading external resources and that nullifying it prevents XXE attacks while maintaining XML parsing functionality.

Public Method XML Processing

Applications parse XML from public interfaces (web requests, API calls, file uploads) without proper security configuration. This occurs when XML processing logic doesn't differentiate between trusted internal XML and untrusted external input, applying the same parsing configuration to both.

Fixes

1

Disable External Entity Resolution

Set XmlDocument.XmlResolver = null to prevent external entity resolution. This completely disables the ability to load external DTDs and entities while preserving normal XML parsing functionality. This is the most effective defense against XXE attacks in XmlDocument.

2

Use Secure XmlReaderSettings

When using XmlReader with XmlDocument, configure XmlReaderSettings with DtdProcessing = DtdProcessing.Prohibit and XmlResolver = null. This provides defense-in-depth by preventing DTD processing at multiple layers of the XML parsing stack.

3

Implement Input Validation

Validate XML input before parsing to detect and reject malicious payloads. Check for DTD declarations, external entity references, and suspicious XML structures. Consider using XML schema validation to ensure input conforms to expected formats before processing.

Detect This Vulnerability in Your Code

Sourcery automatically identifies c# xmldocument xxe via dtd processing of public input and many other security issues in your codebase.