XML External Entity Injection
Example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY bar SYSTEM "file:///etc/passwd" >]>
<trades>
<metadata>
<name>Apple Inc</name>
<stock>APPL</stock>
<trader>
<foo>&bar;</foo>
</trades>
public static DocumentBuilderFactory newDocumentBuilderFactory() {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", true);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", true);
} catch(ParserConfigurationException e) {
throw new RuntimeException(e);
}
return documentBuilderFactory;
}
}
Remedy:
For example with Java XMLInputFactory:
xmlInputFactory.setProperty(
XMLInputFactory.SUPPORT_DTD, false
);
Let's see how the above fix can be applied to our vulnerable example to remediate the XXE vulnerability.
Improved code :
public class TradeDocumentBuilderFactory {
public static DocumentBuilderFactory newDocumentBuilderFactory() {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
// documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", true);
// documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", true);
documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
} catch(ParserConfigurationException e) {
throw new RuntimeException(e);
}
return documentBuilderFactory;
}
}
- If users are allowed to upload XML files which your server is going to parse, you are at risk.
- An XXE attack works by taking advantage of a feature in XML, namely XML eXternal entities (XXE) that allows external XML resources to be loaded within an XML document.
- By submitting an XML file that defines an external entity with a file:// URI, an attacker can effectively trick the application's SAX parser into reading the contents of arbitrary file(s) that reside on the server-side filesystem.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY bar SYSTEM "file:///etc/passwd" >]>
<trades>
<metadata>
<name>Apple Inc</name>
<stock>APPL</stock>
<trader>
<foo>&bar;</foo>
</trades>
- Java web applications using XML libraries are particularly vulnerable to external entity (XXE) injection attacks because the default settings for most Java XML SAX parsers is to have XXE enabled by default.
- To use these parsers safely, you have to explicitly disable referencing of external entities in the SAX parser implementation you use. We'll revisit this in the remediation section later.
- Problem code:
public static DocumentBuilderFactory newDocumentBuilderFactory() {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", true);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", true);
} catch(ParserConfigurationException e) {
throw new RuntimeException(e);
}
return documentBuilderFactory;
}
}
Remedy:
- Because user supplied XML input comes from an "untrusted source" it is very difficult to properly validate the XML document in a manner to prevent against this type of attack.
- Instead the XML processor should be configured to use only a locally defined Document Type Definition (DTD) and disallow any inline DTD that is specified within user supplied XML document(s).
- Due to the fact that there are numerous XML parsing engines available for Java, each has its own mechanism for disabling inline DTD to prevent XXE. You may need to search your XML parser's documentation for how to "disable inline DTD" specifically.
For example with Java XMLInputFactory:
xmlInputFactory.setProperty(
XMLInputFactory.SUPPORT_DTD, false
);
Let's see how the above fix can be applied to our vulnerable example to remediate the XXE vulnerability.
Improved code :
public class TradeDocumentBuilderFactory {
public static DocumentBuilderFactory newDocumentBuilderFactory() {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
// documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", true);
// documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", true);
documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
} catch(ParserConfigurationException e) {
throw new RuntimeException(e);
}
return documentBuilderFactory;
}
}
No comments:
Post a Comment