XML standard allows the use of entities, declared in the DOCTYPE of the document, which can be internal or external.
When parsing the XML file, the content of the external entities is retrieved from an external storage such as the file system or network, which may lead, if no restrictions are put in place, to arbitrary file disclosures or server-side request forgery (SSRF) vulnerabilities.
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE person [ <!ENTITY file SYSTEM "file:///etc/passwd"> <!ENTITY ssrf SYSTEM "https://internal.network/sensitive_information"> ]> <person> <name>&file;</name> <city>&ssrf;</city> <age>18</age> </person>
It’s recommended to limit resolution of external entities by using one of these solutions:
For DocumentBuilder, SAXParser, XMLInput, Transformer and Schema JAPX factories:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // Noncompliant SAXParserFactory factory = SAXParserFactory.newInstance(); // Noncompliant XMLInputFactory factory = XMLInputFactory.newInstance(); // Noncompliant TransformerFactory factory = javax.xml.transform.TransformerFactory.newInstance(); // Noncompliant SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // Noncompliant
For Dom4j library:
SAXReader xmlReader = new SAXReader(); // Noncompliant
For Jdom2 library:
SAXBuilder builder = new SAXBuilder(); // Noncompliant
For DocumentBuilder, SAXParser, XMLInput, Transformer and Schema JAPX factories:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // to be compliant, completely disable DOCTYPE declaration: factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // or completely disable external entities declarations: factory.setFeature("http://xml.org/sax/features/external-general-entities", false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); // or prohibit the use of all protocols by external entities: factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); SAXParserFactory factory = SAXParserFactory.newInstance(); // to be compliant, completely disable DOCTYPE declaration: factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // or completely disable external entities declarations: factory.setFeature("http://xml.org/sax/features/external-general-entities", false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); // or prohibit the use of all protocols by external entities: SAXParser parser = factory.newSAXParser(); // Noncompliant parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); XMLInputFactory factory = XMLInputFactory.newInstance(); // to be compliant, completely disable DOCTYPE declaration: factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // or completely disable external entities declarations: factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); // or prohibit the use of all protocols by external entities: factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); TransformerFactory factory = javax.xml.transform.TransformerFactory.newInstance(); // to be compliant, prohibit the use of all protocols by external entities: factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // to be compliant, completely disable DOCTYPE declaration: factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // or prohibit the use of all protocols by external entities: factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
For Dom4j library:
SAXReader xmlReader = new SAXReader(); xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
For Jdom2 library:
SAXBuilder builder = new SAXBuilder(); builder.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); builder.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");