SQL Injection Stopped Cold with ColdFusion

I woke up this morning to hundreds of alert emails from one of my websites. It seems while I was sleeping someone or "somebot" tried a SQL Injection attack on this site and they (or the bot) failed miserably. Why did they fail? I properly use CFQUERYPARAM.

The fundamental problem in SQL injection is concatenation of untrusted data (raw user input) to trusted data and the whole strings is being sent to the database for execution. The moment you merge the raw untrusted data to trusted data for execution, you got a problem. You should never allow raw data get to the database.

The nature of this attack was to append to a URL param like this.

view plain print about
1action=song&prod=11866+and+1=0+%20Union+Select+......... (I'm leaving off the encoded SQL)

My alerts told me that the value failed for the data type. Part of the reason for using the CFQUERYPARAM tag is to enforce data protection by using the CFSQLTYPE and MAXLENGTH attributes.

view plain print about
1<!--- borrowed from the ColdFusion 8 LiveDocs
2http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=Tags_p-q_18.html
3--->

4 <cfquery name = "query name" dataSource = "data source name" ...other attributes...
5 SQL STATEMENT column_name =
6 <cfqueryparam value = "parameter value"
7 CFSQLType = "parameter type"
8 list = "yes|no"
9 maxLength = "maximum parameter length"
10 null = "yes|no"
11 scale = "number of decimal places"
12 separator = "separator character">

13 AND/OR ...additional criteria of the WHERE clause...>
14 </cfquery>

This SQL Injection attack was prevented because the datatype was not integer. If this was a string field then it would have failed due to the MAXLENGTH attribute except for maybe on some very long fields. Next, because CFQUERYPARAM creates a Prepared Statement instead of raw SQL, essentially encapsulating the raw data and preventing it from being executed.

In addition to stopping these types of attacks you need to know when these attack happen. I was sound asleep when these happened, and I really don't feel like reading miles of log files every morning to check to see if something happened. I've setup email notification for these types of errors so that I get alerted to a threat and can then check to make sure nothing else happened. I know a lot of people that never log these things and still many more that log these errors but never review the log files. Trust the logs! Believe the logs! The logs aren't lying. Reading the logs are time consuming (and can cure insomnia) which is why some sort of log scanning tool and notifications should be setup. You can't stop an attack if you don't know about it.

In this case the code blocked the attack, my alerts told me about it and I went on with my morning consuming caffeine.

Serving File Downloads with ColdFusion

I frequently get asked about providing links to files to be downloaded from ColdFusion websites. Many people will just create a direct link to the file that downloaded such as "myfile.pdf", but by doing it this way you have no control over how the end user's browser is going to access that file. Controlling how the end-users browser accesses the file is very simple with ColdFusion. This can be done in ten lines of code or less. And the benefit of doing it this way is you also mask the location on your file server where your downloaded files are stored. And by doing it this way you could even place these download files outside of the web root for even greater security.There isn't much to it just three tags; cfSet, cfHeader and cfContent. Create a new file and name it something like filedownload.cfm and copy the code below into that file and save it. The only thing you should have to do is modify the line that has "[ PATH TO YOUR FILES FOR DOWNLOAD ]" by setting the correct folder path. You should be able to test this by modifying the code that would normally have a link to the file and change the link to call this file and pass is the filename of the file to be downloaded. The link would should look like something like this: filedownload.cfm?filename=myfile.pdf.

view plain print about
1<cfset folder = "[ PATH TO YOUR FILES FOR DOWNLOAD ]">
2<cfif StructKeyExists(url,"filename") && fileExists(folder & filename)>
3    <cfset filename = "#url.filename#">
4    <cfset fileInfo = GetFileInfo(folder & filename)>
5    <cfset mimeType = getPageContext().getServletContext().getMimeType(folder & filename)>
6    <cfheader name="Content-Disposition" value="attachment; filename=""#filename#""">
7    <cfheader name="Expires" value="#Now()#">
8    <cfheader name="Content-Length" value="#fileInfo.size#">
9    <cfcontent type="#mimeType#" file="#folder##filename#" deletefile="No">
10</cfif>

So what am I doing here?

  1. Checking to make sure a filename was passed and that it exists!
  2. Getting the file size using getFileInfo.
  3. Getting the mime type using a little CF mixed with Java.
  4. Setting the header Content-Disposition. This is critical. By specifying the key word Attachment you will be forcing all browsers to download the file using the default download tool. If you specify 'Inline' you can force the browser to try to display the file inside the browser window. Since Internet Explorer can open many MS Office documents in the browser window you need to specify which you want to happen.
  5. Set the header Expire to now() so the browser will not cache the file.
  6. Specify the length of the content (ie file size) the the browsers download manager can correctly estimate the download time and amount remaining. A nice thing to do for your users when having them download large files.
  7. Delivering the file to the browser using cfContent. This also specifies the file mime type and file name so the browser download manager knows how to handle the file and the name it should use to save the file.

And that is how you should serve up a file to be downloaded using ColdFusion. It's quick and easy.

*Note: When I write little tools like this I'm usually writing it because there is something I absolutely need to see in order to complete another project. These little tools are not written as projects themselves and therefore may not be very pretty or as full featured as something that I was writing as a complete project. I just needed to get some code running that gave me back the data I needed to see. There are no warranties or promises. If you find is useful then great. If not, oh well. I know the code works on CF9 at the moment. I can not be certain if it still works on other versions of ColdFusion. * Any code posted may not be totally secure or production ready. Use at your own risk. ** Unless otherwise noted, this code shall be deemed Public Domain.

Migrating to ColdFusion Builder from CFEclipse

Many people have been using CFEclipse for several years now and are now migrating to ColdFusion Builder. Since both are Eclipse based products this is pretty simple, but there are a few things that will not migrate without manual intervention.

First start with installing ColdFusion Builder. (See this.)

Next lets import your CFEclipse Projects. You can do this and it is easy since it is really an Eclipse feature not specific to any add-ons. Right click in the Navigator view and choose "Import". The windows that opens give you many options for what to import. You are going to click and expand the "General" folder and then choose "Existing Projects into a Workspace" and click the Next Button.

If you are using an SVN and you plan to use an Eclipse SVN plug-in in ColdFusion Builder install that plug in before importing your projects, the import process will automatically reconnect the imported projects to your SVN(s). You will also want to configure the SVN plug-in to access all repositories before you run the imports.

[More]

Homebrewed ColdFusion Monitor Presentation Files

Recently I presented Homebrewed ColdFusion Monitoring to the Twin Cities CFUG and to the Online ColdFusion Meetup.  Both presentations went well and I've been asked to post my slides and example code. 

Attached to this post is a zip file that contains a PDF version of my slides and the example code plus the CFC I'm using to make a full featured monitoring application.  Please note that the code is for CF9 Enterprise.  There may be some things that won't work in earlier versions of CF or the standard edition of CF.
 
The recording for my live presentation is at http://experts.na3.acrobat.com/p34004904/
 
Enjoy and watch RIAForge.  I am planning to release this application to the ColdFusion Community for collaborative development.
 
Thank you to all that attended the presentations and for your wonderful feedback.
 
Wil
 

*UPDATE* - I just uploaded a new zip file with corrected code that actually works this time.

*Note: When I write little tools like this I'm usually writing it because there is something I absolutely need to see in order to complete another project. These little tools are not written as projects themselves and therefore may not be very pretty or as full featured as something that I was writing as a complete project. I just needed to get some code running that gave me back the data I needed to see. There are no warranties or promises. If you find is useful then great. If not, oh well. I know the code works on CF8 at the moment. It used to work on CF7, but I do not have a CF7 server anymore so I can not be certain.

RegEx IP Address Validation

RegEx IP Address Validation

I recently had a project at work where I had to add in some strict IP Address validation and restrictions. We are being required to prevent end users from entering certain IP addresses or ranges. This is a perfect task for Regular Expressions. I am not an expert in RegEx, but I can get out basic RegEx expressions. The first thing I did was search around the net to see if there were expressions already done for IP addresses. There are, but not entirely what I needed. The best I could find were expressions to validate the IP address to ensure it is valid. I didn't find anything to test for certain ranges of IP Addresses. Since I can hack at RegEx a bit I took the expression I found to validate the IP address and made modifications to do the tests I needed. These are the Regular Expressions I hacked up to do the validation and restrictions.

We were required to block these IP addresses or ranges.

view plain print about
10.0.0.0
2127.0.0.1
3255.255.255.255
410.0.0.0 - 10.255.255.255
5172.16.0.0 - 172.31.255.255
6192.168.0.0 - 192.168.255.255

[More]

Recursion Fun

I just came across a fun little blog post about benchmarking the new version of Ruby by doing a Fibonacci sequence.  I hadn't thought about playing with Fibonacci sequences in a long time and since several others did it already I didn't really try.  I just ran one of the CF code examples someone posted on my MacBook Pro.  I blinked and missed the execution of it. Meh, fast enough.  

Like I said I hadn't thought about Fibonacci or other such algorithms in a long time.  At least not much since college when we all learned such things along with various sorting algorithms (who can forget the bubble sort?).  Why did we learn those when today we just write something like sort(blah) and never think about how it gets done.  I remember working on analyzing sorting algorithms to see which was the fastest and most memory efficient.  Memory efficient?  That is a novel concept these days.

However, a while back I did a recursion experiment in ColdFusion by doing a Factorial function which in college is one of the classic programming examples used to teach recursion.

I'm not even sure where you would use recursion these days, except in programming classes.  I have not run across the need for it in ages, but for some reason I was compelled to try this little experiment.

Is there really a need for recursion these days, or are we overlooking a power tool?

view plain print about
1<cffunction name="factorial" access="public" returntype="numeric" output="yes">
2    <cfargument name="end_value" required="Yes" type="numeric">
3    <cfif end_value lte 1>
4        <cfreturn 1>
5    <cfelse>
6        Calling myself with #arguments.end_value-1#<br>
7        <cfreturn end_value * factorial(arguments.end_value-1)>
8    </cfif>
9</cffunction>
10<cfoutput>#factorial(100)#</cfoutput>

New blog skin

I got tired of having an ugly blog and I am absolutely NOT a designer.  So I dug around looking for free blog skins and finally found the one I liked best.  Clean, simple and easy to implement with blogCFC.  It's called Nautica 2.2 Liquid [here].  The photo I used in the header is one my wife shot of the new I-35W bridge that spans the Mississippi river in Minneapolis, MN and replaces the one that collapsed (almost on me) back in 2007.  I'll have to have her get me high-res version of that photo so I can rid of the grain.  You can see the full size bridge photos here.

I still have design elements I want to try, but I'll have to do them another day.  It's 3:15am and my alarm goes off at 6am. Yuk.

Well, at least I won't have the ugliest blog on the net any more.  Now I can get back to ColdFusion coding and not be embarrassed by my ugly blog.

Cheers,

Update: Note to self, never write a blog post at 3 in the morning.  Spelling errors!

Update: 3 Days later I looked at my blog with IE.  I HATE IE!  Back to the CSS to compensate for the weakest link.

Update: I finally have it 'good enough' in IE. 

Scripting ColdFusion Restarts on Linux

A long time ago I wrote a bash shell script to monitor ColdFusion 7 and issue a restart if the CF server hung itself or was about to run out of memory.  I posted info on this script at House of Fusion back then. Today I am still getting requests for this script so I am finally posting the script files to my blog (which I didn't have back then).  


Repost from HOF:

My bash script does two things.  It checks a specified URL for a certain string to see if CF is still responsive and it also calls a cf script which reports back an integer that is the amount of free JVM memory left.

If a hang situation is detected the script will pause for a specified amount of time and

[More]

VMWare Fusion, ColdFusion, Open BlueDragon

I'm very new to the world of running Virtual Servers.  It's a strange concept to me.  Even though I manage many of my own physical servers I'm finding it a little hard to grasp this whole concept.  Given that, I've manged to do two different installs today. Oh, I should mention I'm doing this on my Mac Book Pro with a 2.2Ghz Core Dual and 4Gb of ram.  So far I am finding Fusion, VMWare's only Mac offering, to be easy enough to use.  I did manage to install Ubuntu from the ISO, however the mouse behavior was real odd and I never did get the VMTools installed right.  I have more to learn.

I did find a neat website, elasticserver.com. Elastic Server lets you use a web interface to build your VM appliance stack.  I was able to pick the software I wanted on my 'server'.  I chose Open Blue Dragon, JBOSS,

[More]

See all applications and their sessions

Someone at House of Fusion was asking how to see the sizes of sessions in CF7.  While CF8 has a built in Monitoring API but it can have dangerous overhead load on your application, CF7 does not even have that. 

I had run across the need to see all the applications running on our servers and then all the sessions of each application so I wrote a quick little script that uses the java objects "coldfusion.runtime.ApplicationScopeTracker" and "coldfusion.runtime.SessionTracker" to get all the data I was trying to see.

So here is that little  "Random Tool".  (Click on the Download Icon below.)

*Note: When I write little tools like this I'm usually writing it because there is something I absolutely need to see in order to complete another project. These little tools are not written as projects themselves and therefore may not be very pretty or as full featured as something that I was writing as a complete project. I just needed to get some code running that gave me back the data I needed to see. There are no warranties or promises. If you find is useful then great. If not, oh well. I know the code works on CF8 at the moment. It used to work on CF7, but I do not have a CF7 server anymore so I can not be certain.

More Entries