FlawOpen

flawopen.com/XXE/.NET XML readers

Is XmlReader safe from XXE in .NET?

CWE-611: XML External Entity ReferenceReference page
Short answer

Think of a DTD as a parser’s permission slip to fetch documents named inside XML. XmlReader.Create rejects DTDs by default, so an untrusted document cannot use that route unless the application enables it. Legacy APIs and target-framework defaults still matter: explicitly prohibit DTDs and disable external resolution at the parsing boundary.

UNSAFE — legacy or explicitly weakened settings
// Direct legacy reader: DTD parsing can be enabled
// and an external resolver can fetch referenced resources.
var legacy = new XmlTextReader(stream) {
    DtdProcessing = DtdProcessing.Parse,
    XmlResolver = new XmlUrlResolver()
};
while (legacy.Read()) { }

// Explicitly re-enabling DTDs on untrusted XML is risky:
var unsafeSettings = new XmlReaderSettings {
    DtdProcessing = DtdProcessing.Parse,
    XmlResolver = new XmlUrlResolver()
};
using var reader = XmlReader.Create(stream, unsafeSettings);
HARDENED — reject DTDs and external resources
var settings = new XmlReaderSettings {
    // Reject any document that contains a DTD.
    DtdProcessing = DtdProcessing.Prohibit,
    // Defense in depth: never fetch external resources.
    XmlResolver = null,
    // Choose limits for the application’s legitimate input.
    MaxCharactersInDocument = 1_000_000,
    MaxCharactersFromEntities = 1_024,
};

using var reader = XmlReader.Create(stream, settings);
var doc = new XmlDocument { XmlResolver = null };
doc.Load(reader);

Which .NET XML API and framework version are you using?

.NET has several XML APIs whose defaults have differed, and whose defaults have also changed across framework versions. The practical summary:

The .NET Framework 4.5.2 runtime change set XmlReaderSettings.XmlResolver to null and initialized MaxCharactersFromEntities to 10 million; it did not make every XML API or every target configuration equivalent. A compatibility switch can restore legacy defaults. Set parser policy explicitly, bound document size for availability, and inspect the actual target framework and runtime configuration.

FAQ

Does XmlReader.Create prohibit DTD processing by default?

Yes. XmlReaderSettings.DtdProcessing defaults to Prohibit, which throws when a DTD is encountered. Set it explicitly anyway, and set XmlResolver to null as defense in depth.

What changed in .NET Framework 4.5.2?

For security, XmlReaderSettings.XmlResolver defaults to null and MaxCharactersFromEntities is initialized to 10 million. Microsoft documents an EnableLegacyXmlSettings switch that can restore earlier behavior; check deployed configuration, not only the target framework.

Does this affect SOAP, SAML, or Office document parsing?

It can. These formats contain XML, but the effect depends on the specific parser and settings. Ensure each untrusted XML entry point uses a hardened reader; separately bound input size and follow the format library’s own security guidance.

References

See also XML External Entity (XXE) Injection (CWE-611): How It Works and How to Prevent It — flawopen.com Java XXE: Is DocumentBuilderFactory Secure by Default? Python XML XXE Security: ElementTree, Expat, and lxml