Allowing external DTD entities in untrusted documents to be processed could lay your systems bare to attackers. Imagine if these entities were parsed:
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo> <!ENTITY xxe SYSTEM "http://www.attacker.com/text.txt" >]><foo>&xxe;</foo>
If you must parse untrusted XML, the best way to protect yourself is to only accept an embedded DTD or, even better, completely ignore any DTD declared in the document.
This rule raises an issue when any of the following are used without first disabling external entity processing:
javax.xml.validation.Validator
, JAXP's DocumentBuilderFactory
, SAXParserFactory
, Xerces 1 and Xerces 2 StAX's
XMLInputFactory
and XMLReaderFactory
.
To disable external entity processing for XMLInputFactory
, configure one of the properties
XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES
or XMLInputFactory.SUPPORT_DTD
to false.
To disable external entity processing for SAXParserFactory
, XMLReader
or DocumentBuilderFactory
configure
one of the features XMLConstants.FEATURE_SECURE_PROCESSING
or "http://apache.org/xml/features/disallow-doctype-decl"
to
true.
To disable external entity processing for Validator
, configure both properties XMLConstants.ACCESS_EXTERNAL_DTD
,
XMLConstants.ACCESS_EXTERNAL_SCHEMA
to the empty string ""
.
/* Load XML stream and display content */ String maliciousSample = "xxe.xml"; XMLInputFactory factory = XMLInputFactory.newInstance(); try (FileInputStream fis = new FileInputStream(malicousSample)) { // Load XML stream XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(fis); // Noncompliant; reader is vulnerable
/* Load XML stream and display content */ String maliciousSample = "xxe.xml"; XMLInputFactory factory = XMLInputFactory.newInstance(); // disable resolving of external DTD entities factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); // or disallow DTDs entirely factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); try (FileInputStream fis = new FileInputStream(malicousSample)) { // Load XML stream XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(fis);