XML External Entities (XXE)
ColdFusion Security Guide
The Risk
By leveraging a XML External Entity or XXE weakness an attacker can read files, cause a denial of service or make external network requests from your server - a Server Side Request Forgery (SSRF).
A Vulnerable Example
Assume you have the following CFML / ColdFusion code:
xmlParse(form.xml);
And the attacker passes the following payload as form.xml
:
<?xml version="1.0" ?>
<!DOCTYPE d [
<!ENTITY xxe SYSTEM "http://httpbin.org/uuid">]>
<tag>&xxe;</tag>
In this example the attacker defines an an XML External Entity called &xxe;
which is defined as the result of calling the url: http://httpbin.org/uuid
. Whenever &xxe;
appears in the XML document, the XML parser will replace &xxe;
with the HTTP result of the url http://httpbin.org/uuid
The attacker could also read any file on the server that your ColdFusion server process has permission to read.
The billion laughs variant
It is possible to cause a denial of service attack as well using XML External Entity processing in an XML document, here's an example called Billion Laughs (via OWASP):
<!DOCTYPE root [
<!ELEMENT root ANY>
<!ENTITY LOL "LOL">
<!ENTITY LOL1 "&LOL;&LOL;&LOL;&LOL;&LOL;&LOL;&LOL;&LOL;&LOL;&LOL;">
<!ENTITY LOL2 "&LOL1;&LOL1;&LOL1;&LOL1;&LOL1;&LOL1;&LOL1;&LOL1;&LOL1;&LOL1;">
<!ENTITY LOL3 "&LOL2;&LOL2;&LOL2;&LOL2;&LOL2;&LOL2;&LOL2;&LOL2;&LOL2;&LOL2;">
<!ENTITY LOL4 "&LOL3;&LOL3;&LOL3;&LOL3;&LOL3;&LOL3;&LOL3;&LOL3;&LOL3;&LOL3;">
<!ENTITY LOL5 "&LOL4;&LOL4;&LOL4;&LOL4;&LOL4;&LOL4;&LOL4;&LOL4;&LOL4;&LOL4;">
<!ENTITY LOL6 "&LOL5;&LOL5;&LOL5;&LOL5;&LOL5;&LOL5;&LOL5;&LOL5;&LOL5;&LOL5;">
<!ENTITY LOL7 "&LOL6;&LOL6;&LOL6;&LOL6;&LOL6;&LOL6;&LOL6;&LOL6;&LOL6;&LOL6;">
<!ENTITY LOL8 "&LOL7;&LOL7;&LOL7;&LOL7;&LOL7;&LOL7;&LOL7;&LOL7;&LOL7;&LOL7;">
<!ENTITY LOL9 "&LOL8;&LOL8;&LOL8;&LOL8;&LOL8;&LOL8;&LOL8;&LOL8;&LOL8;&LOL8;">
]>
<root>&LOL9;</root>
Not so funny actually :-)
Where to look in your CFML code?
Any place in your code the deals with XML is potentially vulnerable to this type of attack. This certainly includes tags and functions like:
xmlParse
xmlTransform
xmlValidate
xmlSearch
cfxml
cffeed
isXML
isValid("xml", value)
In addition certain document formats such as docx, xslx contain xml, and the libraries that parse the files could also be vulnerable.
Mitigating XXE in Adobe ColdFusion
The third argument of the xmlParse
function accepts a struct of parser options. You can set allowExternalEntities: false
within that struct
xmlParse(xml, false, {allowExternalEntities: false});
This syntax is also supported on Lucee 5.4.2.20+ and 6.0.0.522+
You can also pass these parser options to isXML
in the second argument:
isXML(xml, {allowExternalEntities: false})
The parserOptions argument is supported as of ColdFusion 2016 or greater.
Mitigating XXE in Lucee
Lucee provides a mechanism in Application.cfc
to control the XML Features:
this.xmlFeatures = {
externalGeneralEntities: false,
secure: true,
disallowDoctypeDecl: true
};
As of Lucee 5.3.11.5, 5.4.2.17, and 6.0.0.519 these settings are enabled by default.
Mitigating XXE at the JVM Level
Java has a builtin XML parsing API called JAXP, which may or may not be used depending on the CFML engine, version or java library that you are using.
Here are some java system properties that you can set to control XML parsing features for the JAXP parser:
javax.xml.accessExternalDTD
- set to an empty string to disable all protocolsjavax.xml.accessExternalSchema
- set to an empty string to disable all protocolsjavax.xml.accessExternalStylesheet
- set to an empty string to disable all protocols
Again, this only applies to the JAXP (Java API For XML Parsing), other java based xml parsers such as xerces would ignore these system properties.
Alternatives to XmlParse
If you want to avoid XmlParse all together, you might consider using SafeXMLParse, which is a XML parser written in CFML meant to return a similar structure as XmlParse does without supporting all the dangerous XML features.
Another option is to convert the XML into JSON using the java class org.json.XML
which is included in both Adobe ColdFusion and Lucee by default. You can call the toJSONObject
and pass your XML String to it, then use deserializeJSON to obtain a CFML structure of the XML content.
createObject("java","org.json.XML").toJSONObject(xmlString)
The XML to JSON technique was inspired by James Moberg.
Additional Mitigation Techniques
This should be fixed at the code level, however you can limit the potential damage of an XXE attack by restricting the file system permissions, enabling sandbox security or restricting outbound network connections.
Additional Resources
- XML External Entity Cheatsheet - OWASP XML External Entity Cheatsheet
- Java JAXP Guide - Java JAXP XML Processing Security Guide
- LDEV-1676 - Lucee Ticket to add the
this.xmlFeatures
setting in Lucee - LDEV-3451 - Lucee Ticket for defaulting
this.xmlFeatures
setting to be secure by default.
Scanning your code for XML Entity Injection
Fixinator can scan your code and detect some XML Entity Injection vulnerabilities within your ColdFusion source code.
Mitigating with FuseGuard
FuseGuard provides a XMLEntityInjectionFilter
which can block requests that contain an XML External Entity definition. You should however always rely on code level fixes instead of WAF layer fixes as they may not block 100% of the possible attack vectors.