Safeguard
Security Guides•

XXE prevention checklist: disable DTDs in your XML parsers

The core XXE fix is to disable DTDs in every XML parser. Use this checklist for Java, .NET, Python and PHP, plus the places teams forget to harden.

Safeguard Security Team
3 min read

Disable document type definitions in every XML parser that handles untrusted input. OWASP's main advice is to turn DTDs off whenever possible. If you need them, disable external entity resolution and external DTD loading, and limit entity expansion. If a parser cannot apply a safety setting, treat that as a configuration failure.

What XXE does

XXE happens when an XML processor resolves an external entity from untrusted input. OWASP lists the impact as exposing local files, enabling server side request forgery, or exhausting resources. It also notes that stopping XXE does not stop every XML denial of service attack, so entity expansion needs its own limits.

Language checklist

These notes come from the OWASP XXE cheat sheet. Check the current page for exact code before you copy settings.

Java.

  • For DocumentBuilderFactory and SAXParserFactory, set the disallow-doctype-decl feature and enable secure processing.
  • For StAX XMLInputFactory, set SUPPORT_DTD and IS_SUPPORTING_EXTERNAL_ENTITIES to false and install a resolver that rejects external references.
  • For TransformerFactory and SchemaFactory, restrict the ACCESS_EXTERNAL_* properties before use.
  • Do not use java.beans.XMLDecoder on untrusted input.
  • Note that setExpandEntityReferences(false) is not a substitute.

.NET.

  • XmlDocument has a null resolver by default from .NET Framework 4.5.2.
  • XmlTextReader is unsafe by default before 4.5.2. Set DtdProcessing to Prohibit.
  • In ASP.NET, the httpRuntime targetFramework in Web.config must be 4.5.2 or later.

Python. Use the defusedxml interfaces for untrusted XML and forbid DTDs where unneeded. OWASP also says Expat versions below 2.7.2 may have denial of service issues, and your Python version alone does not tell you the Expat version.

PHP. Avoid LIBXML_NOENT, LIBXML_DTDLOAD and LIBXML_DTDVALID on untrusted XML unless external resources are blocked.

Places teams forget

  1. Schema validation and style sheet processing. OWASP says to apply external access restrictions there as well, not only to parsing.
  2. XInclude. Keep it disabled unless needed.
  3. Input size. Limit input and decompressed size. OWASP notes the standard library xmlrpc module is exposed to decompression bombs.
  4. Parameters as file paths or URLs. Pass input as streams, not untrusted filenames or URLs.
  5. Formats built on XML. Many document, image and message formats are XML under the hood, so any parser that opens them is in scope. The OWASP page does not detail these, so confirm the parser settings for each pipeline.

Finding gaps

  • Use code search for each parser class named above and check the surrounding configuration.
  • Add a static analysis rule for factories without the DTD setting. OWASP mentions Semgrep rules for Java factories.
  • Review your dependencies, because a library may parse XML on your behalf with default settings. An SBOM helps you see which XML libraries and versions you ship.

Test it

Send a small XML document that declares a DOCTYPE with an external entity pointing to a harmless local test file, in a non production environment. A hardened parser should reject the DOCTYPE or refuse to resolve the entity. If the file contents appear in the response or an error, fix the parser.

Quick check

Is it enough to switch to JSON for new APIs?

It removes XXE from those APIs. Legacy endpoints, file imports and SOAP style services still need the hardening above.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.