Recently, I received a phone call from a former client about an application
I worked on in 2001. The e-commerce site was written during the ColdFusion
5 days and has been running ever since. Unfortunately, he was calling
to say they'd been hacked. Below are the steps I took to secure the application
against sql injection, cross-site scripting attacks and general probing by
hackers.
Step 1 - Upgrade to ColdFusion 7 or higher
Running ColdFusion applications on pre-ColdFusion MX (6.1) servers poses some
security risks. Upgrade to ColdFusion 7 or 8 to take advantage of the
security measures in this post. One caveat before you upgrade. Test
out your application on the new version of ColdFusion before deploying it
to your production server. I can't stress this enough. You don't
want your customers seeing errors because you haven't tested out your old
code on the new version of ColdFusion.
One error I found with my client was the use of dot notation when naming
application variables. For example, we set common email addresses in
the Application.cfm file and used names like application.email.service = "jim@acme.com". This
works fine under ColdFusion 5, but throws a java.exception in ColdFusion MX
and higher. Why is this? Newer versions of ColdFusion added
dot notation for simple assignment of structure values "object.property" is
a value for the structure called "object". Read more about Structures.
Step 2 – Move from Application.cfm to Application.cfc
Ben Nadel does a great job breaking down the
features
of Application.cfc in this post.
Hackers want information about your application, code, database, etc. "Oh,
the better to hack you with my pretty." (said in your best evil witch voice).
Use the OnError() function of Application.cfc to do a few things. See
the code below
<cffunction name="onError">
<cfargument name="Except" required=true/>
<cfargument type="String" name = "EventName" required=true/>
<!--- Throw validation errors to ColdFusion for handling. --->
<cfif Find("coldfusion.filter.FormValidationException",Arguments.Except.StackTrace)>
<cfthrow object="#except#">
<cfelse>
<!--- First,
display a generic message for anyone who encounters an error. --->
<cfoutput>
<div>
Opps, an application error has occured. The webmaster has been notified.</a>.
</div>
</cfoutput>
<!--- Second, fire off
an email alerting you an error was generated.--->
<cfmail to="myname@mydomain.com" from="myname@mydomain.com" subject="Application
Error" type="html">
<cfdump var="#except#" label="Error Details">
</cfmail>
</cfif>
<!--- Third, log all errors in an application-specific log file for later
review. --->
<cflog file="#This.Name#" type="error" text="Event
Name: #Eventname#" >
<cflog file="#This.Name#" type="error" text="Message:
#except.message#">
</cffunction>
The less hackers know about your application the better.
Step 3 – Secure any variables passed via Forms or URLs.
Variables passed via URLs are especially vunerable to hackers. Two ways
you can secure them. First use <cfparam> and set the type
for any numeric values.
For example, foo.cfm?id=1 can easily be modified
to foo.cfm?id=1 and 1 = convert(int,(select top table_name from information_schema.tables)).
Add cfparam at the top of your page to prevent non-numeric values.
<cfparam name="id" default="0" type="numeric">
You should also secure all values passed into the cfquery
tag. ColdFuion
MX and higher support the <cfqueryparam> tag. Use it at all times.
Here is the non-secure query
<cfquery name="login" datasouce="#application.dsn#">
select *
from Users
where UserName = #form.username#
and Password = #form.password#
</cfquery>
Here is the secure query
<cfquery name="login" datasouce="#application.dsn#">
select *
from Users
where UserName = <cfqueryparam
value="#form.username#" cfsqltype="CF_SQL_VARCHAR">
and Password = <cfqueryparam
value="#form. password #" cfsqltype="CF_SQL_VARCHAR">
</cfquery>
STEP 4 – Protect against malicious html code (cross-site scripting attacks).
Hackers will try to insert html code to attack you and/or your users. They
will use the <script>, <object>, <embed> and other tags to
run malicious code through your site.
ColdFusion 7 Administrator has a setting you can turn on to protect against
such an attack. Login to the ColdFusion Administrator, and click
on Settings. Near the bottom is a check box for Specify
whether to protect Form, URL, CGI, and Cookie scope variables from cross-site
scripting attacks. Check that box!
If you want extra protection or can't access the ColdFusion Administrator,
there is a great custom tag called CodeCleaner. Download
CodeCleaner here and place it with your other customtags. Then add
this code at the top of your page.
<CF_CodeCleaner INPUT="#form.UserName#"><cfset form.
UserName =clean_code>
<CF_CodeCleaner INPUT="#form.Password#"><cfset form.
UserName =clean_code>
This will remove any "bad" html a hacker may try to insert into
pages or a database.
That's it for Part 1 of securing your ColdFusion Applications.
If you have suggestions for Part 2, please let me know and Happy Coding.