ColdFusion Securely Storing Passwords

Consider the following code that implements a simple login.

view plain print about
1<cfquery name="user" datasource="#request.dns#">
2select * from users
3where name = '#form.login#' and password = '#form.password#'
4</cfquery>
5
6// if login failed go back to login page
7
<cfif user.recordcount is 0>
8 <cflocation url="login.cfm">
9</cfif>

One of the issues with this is that the password is stored in the database as plain text. Anything with access to the database (including your ColdFusion application) could possibly be used to get a list of all users and their passwords.

The simple way to solve this to to store a hash of the password rather than the password itself.

What's a hash? A hash is a function that takes a string and then converts it to a number (usually hexadecimal) that represents the string. However give a hash number it virtually impossible to convert it back to the string or find another string that gives the same hash value.

You can think of a hash as a fingerprint of a piece of text. For more see the entry on hash functions in Wikipedia.

So instead of storing the passwords in the database you stored the hash of the password. The above code then becomes:

view plain print about
1<cfquery name="user" datasource="#request.dns#">
2select * from users
3where name = '#form.login#' and password = '#hash(form.password)#'
4</cfquery>
5
6// if login failed go back to login page
7
<cfif user.recordcount is 0>
8 <cflocation url="login.cfm">
9</cfif>

NOTE:This code is an example only and all ColdFusion queries including the one above should use cfqueryparam in order to be secure and hinder SQL injection style attacks.

The only downside to this is that if a user of your application forgets their password you would need to generate a new password for them.

TweetBacks
Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
I realize that you are aiming for simplicity in this example, but implementing this code as-is exposes a site to a huge sql injection vulnerability. form.login and form.password should be either scrubbed or else use cfqueryparam.
# Posted By Marc | 4/5/07 1:23 PM
Best practice is to use cfqueryparam in your queries.

This was just a simple example to show the use of the hash function and a full login example would involve a lot more code and need to address other security concerns. eg Should you pass the password to the cfloginuser tag? (I'll save this for another day.)

SQL injection attacks are more of a problem with queries that contain integer values rather than strings, but the above code would be susceptible to this style of attack with some databases.

Also cfqueryparam does a lot more than just protect from SQL injection attacks it can improve performance. For more see Ben Forta's article http://www.adobe.com/devnet/coldfusion/articles/be...
# Posted By Justin Mclean | 4/5/07 1:44 PM