“Secure by Default” doesn’t seem to be ColdFusion’s motto

By Patrick Toomey

It is a trivial truth, but it doesn’t make it any less so: secure development is not easy.  Given the dynamics at play in the majority of companies many developers are incentivized to produce code as quickly as possible.  There are often promises made to customers, impending marketing efforts with immovable (ex. holiday related) deadlines, etc.  So, as much as I enjoy security from a purist’s standpoint, I also recognize security is obviously placed in the context of countless other, potentially equally valid, constraints.  Given that, it is always nice to see anything that can be done to help developers write more secure code.  For example, take a feature that has an infamous history: file uploads.  Years ago it felt like nearly every file upload I came across was riddled with horrible flaws.  Fast forward to the average Ruby on Rails assessment I run across.  The community has built a large library of tested components that can be modularly incorporated into new projects, including handling file uploads.  I’m not saying I have never run across a file upload vuln in a Rails app, but the proportion has dropped precipitously from the days when everyone was just inventing their own.  I think this is a direct result of Rails frameworks that really are repurposable and don’t require devs to rip them apart to reuse for their application.

This got me thinking about what should be the king of the hill when it comes to this type of object reuse; Rapid Application Development (RAD)/4GL languages/frameworks.  These platforms often include a good number of built-in mechanisms for handling common functionality.  The RAD  platform I have been taking a look at most recently is ColdFusion. Similar to many of the 4GL vendors, ColdFusion seems to target developers that want a “batteries included” kind of development environment.  In other words, many of these frameworks tend to allow for extremely rapid development, so long as the project doesn’t deviate too far from their target market.  In theory I love the idea, as many straight forward CRUD type applications can be rapidly developed without reinventing the wheel (or having to cobble together a bunch of disparate libraries).  Again, in theory, another benefit of these kinds of development environments is security.  These frameworks generally provide fairly abstracted interfaces to features that are security relevant.  Examples include session management, database interaction, encryption, etc.  However, it seems as though when I come across these RAD/4Gl development frameworks I am usually more let down than encouraged by what they offer.  As was the case with a recent assessment involving ColdFusion.

While not a complete list by any means, and these are not likely to surprise ColdFusion experts,  here are a few things that popped up pretty quickly on a recent assessment:

Session cookies use CFTOKEN by default – An upper bound for the entropy provided by this is around 26 bits (which is extremely small relative to other contemporary session tokens).  However, to make things worse, after performing the suite of entropy tests baked in to Burp, it is coming up with 5 bits of entropy.  I haven’t done a ton of analysis, but there are all sorts of bit level correlations going on.

Encryption uses an “insecure by default” primitive – By default, the “Encrypt” function builtin to ColdFusion takes whatever password you provide (of unlimited length), hashes that down to a 32 bit value, and uses that as the seed for a stream cipher.  Given the same password, the stream cipher will generate the same key stream, using no IV at all.  So, given access to any encrypted data, you can retrieve the plaintext and/or create your own ciphertext (it is the exact same kind of attack I described here ).

SQL Injection prevention – ColdFusion has a mechanism for parameterized queries built in to their database abstraction (cfqueryparam for those familiar with ColdFusion).  However, they also, by default, have a mechanism that escapes certain characters in the context of a database query.  I have seen devs find this out and abandon the parameterized queries because ColdFusion “handles this for us”.  However, this built-in protection has weird edge cases that make it’s use somewhat dangerous.  The most recent example I encountered with it was the following (i is a counter):

SELECT A WHERE B= ‘#Form.C#’ AND D= ‘#Evaluate(“Form.element_” & i)#’

By default, the bultin protections escape single quotes found in user posted values.  In other words, their automatic escaping would have been effective if the query were:

SELECT A WHERE B= ‘#Form.C#’ AND D= ‘#Form.element_” & i#’

But, it turns out the escaping occurs before the Evaluate is performed.  So, it essentially does the escape on the string “Form.element_1” (assuming i is 1).  Since there are no illegal characters the Evaluate then retrieves the value from the form field.  The net result was complete access to the database.  This behavior is completely non-obvious.  I would have expected that everything, even after evaluation, between the ‘#’ delimiters to have been escaped.  There is nearly zero chance the average ColdFusion developer is going to understand when/why some things are escaped and some other things are not.

This isn’t to say that we should expect frameworks to guarantee error free code; we can always manage to mess things up 🙂  The hope is that with these RAD environments it would make getting things wrong more difficult, by making the default built-ins relatively secure and force the developer to choose the less secure approach.  As it stands, ColdFusion allows developers to optionally use a random UUID for a session token.  ColdFusion optionally allows developers to specify a more contemporary encryption algorithm.  And again, ColdFusion optionally lets developers use parameterized queries.  It is just a shame all these things are options and not the defaults.  I know there is probably a dozen reasons why these things are implemented as they are, and I am sure much of it has to do with legacy (doesn’t everything involve legacy :-)).  That said, these platforms are often used by developers that don’t have the security savvy to make wise use of things that are optional, and depend on the platform to have thought about these things for them.

4 thoughts on ““Secure by Default” doesn’t seem to be ColdFusion’s motto

  1. Umm . . . you do know about cfqueryparam, don’t you?

    • I am definitely familiar with cfqueryparam; I generalized the term in the article and called it a parametrized query (I’ll update the entry to clarify for those that are unfamiliar). Some developers understand that they should be using cfqueryparam to perform queries, but I have often seen ColdFusion developers fail to use cfqueryparam because, as mentioned in the article, the devs often think the automatic protection built-in to ColdFusion “handles this for us”. There is an argument to be made that automatic protections that only half-way work may be worse than no protection at all, as it gives people a false sense of protection and requires understanding the subtlety of when/where the protections are insufficient.

  2. Most programming environments are insecure by default. Ruby is no exception.

    You have to add plugins to RoR to make things secure (just like you said), sometimes the same is true of ColdFusion. I have no doubt you can create injectable SQL queries in Ruby if you don’t use query params as well.

    I do agree with you that session tokens should be changed to a secure default and that encryption should have a secure default algorithm. I have been encouraging Adobe to take these steps along with fixing a few other insecure defaults.

    I get the feeling from your post that you have the impression that ColdFusion is less secure than other platforms, and that just isn’t true. All platforms have room for improvement in security.

    • All platforms absolutely have room for improvement…that’s for sure. And I definitely take your point about Rails developers leveraging plugins. My main point about the sql injection was that their implementation has a bizarre edge case, whereby the automatic escaping of special characters completely depends on context. The escaping works ok for base case parameters substitution (i.e. Form.element_name), but broke down if the substitution came about as the result of an Evaluate expression (i.e. Evaluate(‘Form.element_name’)). Your comment did make me think, “hmmm, I’ve actually never tried the equivalent in rails”. I guess part of the reason is that I don’t think I’ve come across this idiom in Rails (the vast majority of Rails code I have reviewed leverages the built-in ORM exclusively). But, it would be worth experimenting to see if Rails (or other vendors) have a similar edge case with regard to their auto-escaping sql injection prevention approach.

      My intent wasn’t to bash ColdFusion developers, so I hope the entry didn’t read that way. I am sure you, as well as many other ColdFusion developers, are fully aware of these edge cases and code around them with no problem. It has simply been my experience that many ColdFusion developers (though not all) leverage ColdFusion as a standalone solution and depend upon the platform to be “secure by default”. But, as you said, every vendor can surely stand to do better.

Leave a Reply to Jason Dean Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s