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.