Protecting ColdFusion applications from common attacks

Submitted by Falken on

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.

Sections