Disable External DTD Resolution in XML Parsers
Disabling external Document Type Definition (DTD) resolution is the primary defense against XML External Entity (XXE) injection and XML-based Denial of Service (Billion Laughs) attacks. This guide outlines the specific configuration properties, flags, and code settings required to safely disable external DTDs across modern XML parsers in Java, .NET, Python, PHP, and Node.js.
Java
Java provides multiple XML processing APIs
(DocumentBuilderFactory, SAXParserFactory,
XMLInputFactory, and TransformerFactory). Each
requires explicit feature flags to disable DTD processing.
DocumentBuilderFactory (DOM)
To completely disallow DTDs:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);If inline DTDs are required but external DTD resolution must be blocked:
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);SAXParserFactory (SAX)
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// Or disable external entities specifically:
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);XMLInputFactory (StAX)
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);TransformerFactory / SchemaFactory (JAXP)
Restrict external protocols globally using
XMLConstants:
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");.NET (C#)
In .NET Framework 4.5.2+ and .NET Core / .NET 5+,
XmlReader is secure by default. However, when working with
XmlReaderSettings or legacy XmlDocument,
verify the following properties:
XmlReaderSettings
XmlReaderSettings settings = new XmlReaderSettings();
// Completely prohibit DTDs:
settings.DtdProcessing = DtdProcessing.Prohibit;
// Alternatively, ignore DTDs and remove the resolver:
settings.DtdProcessing = DtdProcessing.Ignore;
settings.XmlResolver = null;XmlDocument
XmlDocument doc = new XmlDocument();
doc.XmlResolver = null; // Disables external entity resolutionPython
lxml
When using lxml.etree, configure the parser options to
prevent network access and entity expansion:
from lxml import etree
parser = etree.XMLParser(
resolve_entities=False,
load_dtd=False,
no_network=True,
dtd_validation=False
)
tree = etree.fromstring(xml_data, parser=parser)defusedxml (Recommended)
Python’s standard xml.etree.ElementTree and
minidom do not resolve external entities by default, but
they are vulnerable to entity expansion attacks. The safest practice in
Python is using the defusedxml package, which overrides
parsers to reject external DTDs automatically:
import defusedxml.ElementTree as ET
tree = ET.fromstring(xml_data)PHP
libxml-based Parsers (DOMDocument, SimpleXML, XMLReader)
In PHP 8.0 and later, external entity loading is disabled by default. For PHP versions prior to 8.0, or to ensure strict compliance:
// Disable entity loading globally (PHP < 8.0)
libxml_disable_entity_loader(true);
// When using DOMDocument, avoid LIBXML_NOENT and LIBXML_DTDLOAD flags:
$dom = new DOMDocument();
$dom->loadXML($xmlString, LIBXML_NONET); // LIBXML_NONET disables network accessNode.js
libxmljs
const libxmljs = require("libxmljs");
const xmlDoc = libxmljs.parseXml(xmlString, {
noent: false, // Do not expand external entities
dtdload: false, // Do not load external DTDs
dtdvalid: false, // Do not validate against DTD
nonet: true // Disable network access
});fast-xml-parser
const { XMLParser } = require("fast-xml-parser");
const parser = new XMLParser({
processEntities: false // Ignores entity parsing
});
const result = parser.parse(xmlString);