According to http://www.theregister.co.uk/2009/09/08/web_app_security_survey/ the top 3 security issues in web applications are:
- SQL injection where end users can effect the SQL executed
- Cross-site scripting (XSS) where users can cause JavaScript to be run by other users
- Cross-request forgery (CSRF) where actions can executed as if a user is logged in, without that user actually having the site open in his browser.
The following explains how ColdFusion can help protect you from each.
SQL injection
Use CFQUERYPARAM in your CFQUERY tags. That's kinda the end of that one for the where clause :-) Everywhere else it basically boils down to 'don't but it in form/url scope to begin with'. So for instance instead of the list of column names to return being a form field (hidden or not) just pass the numeric index or some other stand-in instead, which you can then decode before putting in the CFQUERY.
Cross-site scripting
If you are using ColdFusion's CFAJAX tags or accessing CFCs from JavaScript the easiest thing to do is use the administrator setting "Prefix serialized JSON with".
If you are outputing HTML pages, there are several functions to help you:
htmlEditFormat() should be used around anything the user has control over such as url variables, database columns the user originality entered data for etc.
urlEncodedFormat() should be used for attributes like href, especially when outputting people's email addresses.
jsStringFormat() should be used when outputting into <SCRIPT> tags.
However, none of those are totally sufficient, see ha.ckers.org/xss.html for a list of some seriously wacky XSS vectors to understand why.
The OWASP Encoding Project (Reform Library) which escapes everything except numbers letters and some limited punctuation is the gold standard here. Currently it lacks a CFML implementation however, but you can use the Java one, of course, or see the comments for alternatives.
Cross-request forgery
There's nothing built in, but you can deal with this simply enough.
When you generate a <FORM>, create a random value and store it in the session, and also output it as a hidden field in the form.
When the user submits the form compare the value from the form to the value saved in the session.
You should also make sure that GET requests don't change data (use POST, i.e. forms), though this is good general advice anyway.
Thanks to Dave Watts, Chriss Peterson, Elliott Sprehen, Dean Saxe and all the others who helped with ideas.
Jason Dean adds on
Jason Dean adds on http://www.coldfusionjedi.com/index.cfm/2011/3/7/ColdFusion-Security-Resources that things are not always as easy as they seem... I look forward to his blog post !
OWASP also has a project called AntiSammy which is designed to help protect you from XSS attacks:
http://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project
Since it's Java-based, you can utilize the library in ColdFusion and I even wrote about that here:
http://blog.pengoworks.com/index.cfm/2008/1/3/Using-AntiSamy-to-protect-your-CFM-pages-from-XSS-hacks