# XML External Entity Attacks
**XML External Entity** (XXE) attacks allow a malicious user to read arbitrary files on your server by taking advantage of an unsecured XML parser. If your web-server parses XML you should be sure to disable parsing of inline *Document Type Definitions* (DTDs), since these can be maliciously crafted by an attacker to probe for files on your server.
## Anatomy of an XXE Attack
XML is a useful data format because data files can be checked for correctness before being processed. The structure of an XML document can be validated against a **Document Type Definition** (DTD). DTDs can be inlined in XML documents, and can refer to external entities.
This is where problems can occur. In the process of resolving external entities, an XML parser may consult various networking protocols depending on the scheme specified in URLs. By making clever use of external entity references, an attacker can probe your server for files, hang the parser altogether by referencing URLs that never respond, or trigger fraudulent requests on the server-side.
Below is an example of an XML document with an inline DTD, that references a local file `/etc/passwd`, commonly used to store user information:
“`dtd <?xml version=”1.0″ encoding=”utf-8″?> <!DOCTYPE xrds [ <!ENTITY passwords SYSTEM “file://etc/passwd”> ]> <xrds> &passwords; </xrds> “` |
An unsecured XML parser will expand the file inline during parsing:
“`dtd <?xml version=”1.0″ encoding=”utf-8″?> <xrds> root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin </xrds> “` |
If this expanded XML document is returned to the attacker, or leaked in error messages, the attacker can read arbitrary files on your server in this manner.
“`java @Controller @RequestMapping(“/profile”) public class UserController { @PostMapping public String update(@RequestBody User user) { saveUser(user);return “redirect:/profile”; }private void saveUser(User user) { getDatabase().updateUser(user); } } “` |
## Mitigation
Inline DTDs are a rarely used feature. However, XML external attacks remain a risk because many XML parsing libraries do not disable this feature by default. **Make sure your XML parser configuration disables this feature.** This is done slightly differently depending upon which XML parsing library you are using. You generally have three options, any of which will keep you safe:
* Disable DOCTYPE declarations altogether.
* Disable external entity declarations.
* Disallow any protocols by external entities.
### javax.xml.parsers.DocumentBuilderFactory
“`java DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance;// Disable DOCTYPE declarations: factory.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true); // Disable external entities declarations: |
### javax.xml.parsers.SAXParserFactory
“`java SAXParserFactory factory = SAXParserFactory.newInstance;// Disable DOCTYPE declarations: factory.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true); // Disable external entities declarations: |
### javax.xml.stream.XMLInputFactory
“`java XMLInputFactory factory = XMLInputFactory.newInstance;// Disable DOCTYPE declarations: factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // Disable external entities declarations: |
### javax.xml.transform.TransformerFactory
“`java TransformerFactory factory = javax.xml.transform.TransformerFactory.newInstance;// Prohibit the use of all protocols by external entities: factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, “”); factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, “”); “` |
### javax.xml.validation.SchemaFactory
“`java SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);// Disable DOCTYPE declarations: factory.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true); “` |
## Further Considerations
You should run your server processes with only the permissions they require to function – follow the *principle of least privilege*. This means restricting which directories in the file-system can be accessed. Consider running in a **chroot jail** if you are running on Linux.
This “defense in depth” approach means that even if an attacker manages to compromise your web-server with an XML attack, the damage they can do is limited.
## CWEs
* [CWE-611](https://cwe.mitre.org/data/definitions/611.html)