Wednesday, November 9, 2022

On ColdFusion, XXE, and other XML Attacks

An Introduction

This is the first of what may become a few blog posts based on my CFSummit 2022 talk.  Plus with the release of Adobe Security Bulletin APSB22-44 in October -- which fixed some security bugs that I reported and  improved the available ColdFusion XML security options -- I figured this was also a good opportunity to pull together some ColdFusion XML security best practices into one place.

XML data can live in lots of places, beyond the obvious instances of .xml files and XML-like file formats.  RSS Feeds.  REST API requests and responses.  SAML and SOAP messages.  Office Open XML files such as DOCX, XLXS, PPTX, etc.  And several file formats (such as PDF and PNG) include metadata fields that can contain XML.  

If your application consumes and processes XML, then XML eXternal Entities (XXE) is a vulnerability class that you need to be aware of and protect against.


What is XXE?

An XXE vulnerability can be exploited when a vulnerable XML parser processes XML content that contains a reference to an external entity (such as a URI with a file:/// scheme).  These flaws can be used to read sensitive files, access protected resources, and in some cases be combined with vulnerabilities and configuration weaknesses to even achieve remote code execution.  

For example, a simple XXE payload (malicious XML file) could look something like:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<element>&xxe;</element>


If this is processed by a vulnerable XML parser, the external entity in the XML “element” element will contain the contents of the /etc/password file.  Specific exploitation techniques, blind data exfiltration, and post-exploitation tactics will depend on how the vulnerable application works and other factors, and are beyond the scope of this article.  

For further reading -- XXE is explained in greater detail lots of places online, including these two great write-ups from OWASP and PortSwigger.  And this whitepaper from Tim Morgan and Omar Al Ibrahim remains one of the best resources that enumerates several different XXE exploitation techniques and payloads.


A Real Example – XXE in MuraCMS < 6.2 (CVE-2017-15639)

Let’s look at a real example of an XXE vulnerability in ColdFusion -- CVE-2017-15639, which affected MuraCMS 6.1 and earlier. 

From the original Blueriver advisory: “The vulnerability is related to a rarely-used feature of Mura CMS—the "draggable feeds" content object, which is powered by this single file: {mura root}/tasks/feed/readRSS.cfm”

We can focus in on the vulnerable lines of code in readRSS.cfm here:


As you can see, the application fetches the content from the URL passed in the rssURL parameter, and it’s subsequently processed by xmlParse().  If the fetched XML content contains external entities, these will be expanded as well -- triggering the exploit payload.  This was remediated in MuraCMS by just removing the vulnerable readRSS.cfm file, since it was a little-used feature.

But what might you need to do to secure your applications?


XML Processing in ColdFusion

In ColdFusion/CFML, the following native functions can consume and process XML data: isXML(), xmlParse(), xmlSearch(), xmlValidate(), and xmlTransform().  We’ll be looking at all of these functions, but it’s important to keep in mind that any component that processes XML -- such as third-party software packages or custom code built using add-on Java XML libraries -- would need to be reviewed, tested, and secured as well.

Let’s look at a simple example of some vulnerable CFML code. We’re hardcoding our malicious XML payload as a variable here, but in a real application this would come from some user-controlled source, such as an uploaded file or a fetched URL:


<cfscript>
xmldoc = '<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>';

writedump(xmlParse(xmldoc));
</cfscript>


This code will expand the external entity when it runs, and the contents of /etc/password (assuming it exists and is readable) is displayed.  

Let’s move on to how you can fix this.


How to Configure XXE Protection in Lucee

If your application runs on Lucee, you have it easy since there’s a global application setting to disable support for XML external entities.  As of Lucee 5.3.4.51and later, you can disable support for XML external entities by adding the following to your Application.cfc:


this.xmlFeatures = {
externalGeneralEntities: false,
secure: true,
disallowDoctypeDecl: true
};


Drop these settings above into your Application.cfc, and you will then see that our vulnerable xmlParse() example above will no longer work.

It also sounds like this will be the default config in Lucee 6.0, which is great news.  Secure by default FTW!


How to Configure XXE Protection in Adobe ColdFusion

Preventing XXE in Adobe ColdFusion requires a little more vigilance, since there’s no global setting to disable XML external entities.  As a result, a developer must ensure that every XML function call contains the required security options.  But as of APSB22-44, you have a way to secure all impacted native ColdFusion functions.

The documentation for xmlParse() includes details on how to protect against XXE by setting the parseroptions.ALLOWEXTERNALENTITIES property to false.  


So with this information, we can now secure our earlier example:


<cfset parseroptions = structnew()>
<cfset parseroptions.ALLOWEXTERNALENTITIES = false>

<cfscript>
xmldoc = '<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>';
writedump(xmlParse(xmldoc,false, parseroptions));
</cfscript>


We can make similar changes to secure the other functions that process XML.  For example:


XMLSearch(xmldoc, xpath,parseroptions);

XmlTransform(xmldoc,xslt,parseroptions);

isXML(xmldoc,parseroptions);


And XmlValidate() appears to avoid XXE attacks if you pass it a validator, although my testing against that function may be incomplete.


A Word on XSLT Attacks and xmlTransform() after APSB22-44

In addition to defending against XXE, there are other vulnerability classes related to XML that developers need to account for, such as XPath Injection and XSLT Injection.  Those may be topics for future blog posts.

Some XSLT Injection attacks against ColdFusion were tracked as CVE-2022-42340 and fixed in APSB22-44.  However, the fix appears to be overly restrictive to the point of blocking all XSLT stylesheets, including ones that do not contain malicious content.  After the patch, ColdFusion will return the following error:


Unable to process the XML string as it could probably contain file paths.


if the XSLT contains a / (slash) anywhere including in the closing </xsl:stylesheet> .  For example, a very simple (and not malicious) XLST template will return that error:


<?xml version="1.0" ?> 
<xsl:stylesheet xmlns:xsl version="1.0"></xsl:stylesheet>


As a result, developers must choose between having an  xmlTransform() function that is entirely unusable, or will need to disable XSLT security checks by setting the coldfusion.xml.allowPathCharacters flag to true.  I’ve reported this behavior to Adobe, but at time of posting I have not heard back.


Some Final Thoughts

WAF rules, the Adobe ColdFusion Sandbox, and network egress filtering may provide additional ways to prevent successful exploitation of XXE and other XML-based attacks too -- although you'll want to fix any vulnerable code as well.

Hopefully this information will help you securely process XML in your ColdFusion applications!


Note:  All of the examples above are provided with no guarantee; securing your applications and environments may involve additional actions and considerations.   Plus old vulnerabilities can occasionally sneak into future software releases, so ongoing review and testing is always a good idea.

 

No comments:

Post a Comment