For Better Security Use HtmlEditFormat() In Conjunction With JSStringFormat() In ColdFusion
var jsValue = "#jsStringFormat( cfValue )#";
You just got jammed!
The way this works may not be entirely obvious. In a web-document, you can define character data as a set of encoded ASCII numbers. For example, the tab character - ASCII character 9 - can be rendered using the following HTML:
If you use this approach to render HTML elements, the browser won't interpret the elements, it will simply render the characters. As such, you can't get much malicious mileage out of encoding the "<" and ">" characters. Attributes, on the other hand, are a different beast. If you use this approach to encode attribute values, the browser will interpret them. As such, ASCII-encoded attribute values will work just like plain-text attribute values. And this is where jsStringFormat() falls short.
The jsStringFormat() will attempt to replace the single and double quotes, which would normally limit the damage. But that won't matter here, since we've encoded our quotes as ASCII-values. What we need to do is pass the ColdFusion value through both the htmlEditFormat() and the jsStringFormat() functions:
This way, all of the ASCII-encoded HTML constructs will be escaped as well.
When outputting user-provided content, you should pretty much always use htmlEditFormat(), unless you are completely sure that the content has been sanitized. And, if you need to use jsStringFormat(), don't be fooled into thinking that that is enough escaping. In those cases, you probably need to use both escaping methods for total safety.
Want to use code from this post? Check out the license.
The CF9 equivalent would be
I would echo what Andy says in using the OWASP ESAPI encoders instead of HTMLEditFormat() or JSStringFormat() (and XMLFormat(), URLDecode(), URLEncodedFormat()) since the ESAPI encoders/decoders are much better tested. Because of this there is a good chance that HTMLEditFormat (and other functions that have ESAPI encoders/decoders equivalents) will be deprecated in future releases of ColdFusion.
Also it is possible to get the ESAPI encoders/decoders in CF 9 (and 8 even) by using the line Andy shows, which is similar to what Pete has documented (http://www.petefreitag.com/item/788.cfm). It does require having the ESAPI library installed in CF, which if CF is patched correctly with APSB11-04 or higher it is available. Other choices, ESAPI for CF (https://github.com/damonmiller/esapi4cf), or CFBackPort (https://github.com/misterdai/cfbackport).
Have to agree with David and since the newer versions of CF and Railo have facades for the standard ESAPI methods you can simply run your source through a find&replace once you get rid of any legacy servers.
Groovy stuff. I didn't know that Enterprise Security stuff (ESAPI) was packaged inside of a JAR file. I've only really heard of OWASP in presentations - I haven't done too much R&D with it.
@David, I was just looking at the backports stuff and I see you wrote some "Decode" methods. I'm having trouble finding any info on what they do. Even the ESAPI docs don't really explain what decoding for HTML means?
Does that mean it will _unescape_ things like ampersands and quotes? And, if so, does it do so in some "secure" way? Or is it merely a few utility methods?
@Ben (just to confuse you, another David talking about the same backports project :P)
The DecodeForHTML method simply turns HTML entities back to the characters that they represent. Same goes for the DecodeFromURL which converts URL encoded characters (also supporting double encoded characters) back to the characters they represent.
I don't think it worries about doing anything special with security except for making sure everything is decoded (hence the support for double encoded URL characters).
Keep in mind that the library was added in one of the CF9 updates (and was at least somewhat integrated in CF10). If it fails on a CF9 dev machine be sure to check whether it's missing any updates (running the unofficial updater should take care of that).
Ah, thanks for the insight. As far as the double-encoded URL characters, I assume you're saying that decode-for-html allows URLs to still work after decoding, since they were encoded twice?
Good tip. I'm on CF10 locally, I'll see if I can play around with the lib a bit.
It looks like htmleditformat() will be deprecated in CF 11
Hmmm, and then around half a year ago the whole OWASP ESAPI project was denoted because of lack of support and updates. Now people around the ESAPI "tribe" are referring developers (CF'ers also) to the OWASP Java Encoder project: https://www.owasp.org/index.php/OWASP_Java_Encoder_Project
What are your thoughts on this Ben, especially since CF8+, CF9+, CF10 and CF11 and RAILO all include the ESAPI support, either directly via tags or via a Java object call. Life isn't easy 4 us developers ;-)