It's not very often that you will hear me badmouth ColdFusion, but in this case, I feel compelled. ColdFusion has some truly fantastic features and in many ways make securing web applications easier, but in this case, it has provided little but a false-sense of security.
What is scriptProtect?In case you are not familiar with ColdFusion's scriptProtect feature, it is a pattern matching utility that automatically checks all of the ColdFusion scopes over which an end user has control looking for what it deems is malicious script. It is designed to stop Cross-site scripting (XSS) attacks from being used against your application.
In other words, it checks the CGI, COOKIE, FORM and URL scopes looking for <script>, <meta>, <object>, <embed>, and <applet> tags. When it finds them, it replaces them with <InvalidTag>.
Just as with any countermeasure, scriptProtect is not perfect. The purpose of application security countermeasures is to mitigate risk. Risk can never be completely eliminated, so instead we talk about mitigating risk. This means that we reduce the risk to an acceptable level. So while it is true that scriptProtect does mitigate some risk, it does not reduce it enough to call it an adequate defense for even the most trivial applications.
ExamplesFirst we'll look at some examples where scriptProtect does help.
When testing an application to XSS vulnerability, the first thing most penetration testers will do is try to pass in this value in a URL param or a form field.
So let's use the following CFML document as an example of a vulnerable web page.
<cfparam name="url.name" default="" />
This code is completely vulnerable to XSS attack. But we are not here to look at how to secure this page, right now we are looking at how well scriptProtect can stop attacks against this page.
Let's say that I use the following URL to request the page.
This request would result in a page that says "Hello Jason". How very nice of it :)
But what if I requested the page with this URL?
Now we would get a page that said "Hello alert(123)". And if we looked at the source code we would see:
The InvalidTag would only show up in the source because it is surrounded by <>, so the browser would treat it as HTML, the alert function would simply be rendered as text on the page because it is not in an executable context. The InvalidTag tag succeeded in breaking the executable context that was injected.
This is a situation where scriptProtect works. It blocked the attack and rendered the script useless. It would do the same thing if someone tried to inject an <object> tag to add malicious Java to the page or a nefarious SWF.
But that is where scriptProtect stops being useful. These attacks above (which are what we would expects from complete amateur script-kiddies) are as basic as XSS gets. scriptProtect does nothing against even slightly more advanced attacks. Like these:
http://www.12robots.com/xsstest.cfm?name=<a href="" onmouseover="alert(123)">what am I?</script>
ColdFusion's scriptProtect feature would not stop any of these attacks and these will all work in one browser or another, so even though most of them fail in the most recent version of Google Chrome, they all work in FireFox 3.5. So we need to realize that we cannot count on browser defenses to protect our users.
OptionsDon't get me wrong, I am not telling you to run out and turn off scriptProtect. Some defense is better than none. My point is that if you are counting on scriptProtect to keep your application safe, then you need to stop.
The most important thing to do (but also the hardest) is to go and fix the code in your site that allows for user-generated output to be displayed unmodified. This is where the vulnerability comes from and by removing the vulnerability you will mitigate the risk. I have a post on mitigating XSS risk using HTMLEditFormat(), but it is a bit dated, and I have learned a lot since then. I will need to add more on XSS in the future. I also have an article coming in a future issue of FAQU that goes into great depth on XSS prevention.
Another option you have is to improve the regular expression matching in ColdFusion's scriptProtect. Both Pete Freitag and I have posts on doing this. Even if you opt to do this, it is still not enough. scriptProtect uses blacklist validation, which is never enough.
A third option is to implement a more robust Web Application Firewall (WAF). ColdFusion's scriptProtect is "kind of" a VERY simple WAF. There are MUCH better options out there including:
- Foundeo Fuseguard - FuseGuard, created by Pete Freitag, is a commercial WAF written in CFML and designed for use with ColdFusion applications. It is unique because it works at the application level instead of the web server level. Working at the application level allows you to have different settings for different applications on the same server.
- ModSecurity - ModSecurity, created by Ivan Ristic, is an open-source WAF that has been around for a long time. It has an pretty incredible feature set. It works at the web server level and can be deployed as an embedded proxy or reverse proxy.
- Numerous others commercial and free OSS options are available.
ConclusionLike I said, I do not like to badmouth ColdFusion. I LOVE ColdFusion and CFML. But the more I have looked at scriptProtect and learned about security, the more I realize that scriptProtect just doesn't cut it. And since it has not improved since version 7, I suspect it is not high on Adobe's list of things to look at. I intend to bring this up with Adobe in the future, but for right now, I felt it important for you to realize the shortcomings of this feature.
I have not looked at the implementation of scriptProtect in OpenBD or Railo. I suspect they work similarly.