Securing your ColdFusion Application Part 2

You can find part one of securing your ColdFusion applications here. Part two will focus on securely storing your data.

Step 5 - Use Secure Socket Layer

Use the SSL and https when passing sensitive data to and from your server. This is a no-brainer, but I mention it since passing data insecurely will defeat the purpose storing data securely.

Step 6 - Encrypt your passwords

ColdFusion provides one-way encryption using the hash() function. You won't be able to decrypt the passwords but neither can any hackers. When a user submits their password you'll use the hash function then compare the password with the hashed password value in your database. ColdFusion 7 improved the hash function by adding multiple levels of encryption. Pete Freitag has a nice write up on it at http://www.petefreitag.com/item/270.cfm.

Step 7 - Help users reset forgotten password

In the past developers have used the "forgot password" feature to email users their password or ask them a "secret question/answer". Both methods are a security risk. If you email their existing password, and someone gains access to that email other accounts that use the same password would be compromised. The secret question/answer method may ask the user "the street they grew up on, or high school mascot". This method of password retrieval has gotten more insecure as we share more personal information through social networks. The method I chose is to set a temporary password or reset key in the database and email that to the user. I also insert the date/time of the request so the temporary password/reset key will expire after a period of time (4 to 24 hours).

Step 8 - Encrypt and Decrypt sensitive specifically credit card numbers.

Now, let me start off by saying storing credit card data is risky business. So, unless you really need to store it, you shouldn't. A situation where you might want to store credit card data would be a subscription service. With ColdFusion you can use the encrypt() and decrypt() functions. There are different encryption methods.

 

Application.cfc

 

<cfset request. mySecretKey = GenerateSecretKey('WhateverYouWant')>

 

process.cfm

 

<cfset stringtoDecrypt = "4111111111111111">
<cfset key = request.mySecretKey>
<cfset algorithm = "AES">
<cfset encoding = "hex">

 

#encrypt(stringtoDecrypt, key, algorithm, encoding)#
#decrypt(stringtoDecrypt, key, algorithm, encoding)#

Of course, you could store the secret key in a location other than the application.cfc. This is just an example of how to generate and save the secret key.

Step 9 - Don't use the SA account in the CF administrator

When you create your database, also create a new login user and grant this new user access to your database. But limit access to only database functions you want your application to use. For example insert, update, delete records, but leave out add and dropping tables.

Step 10 - Use Captcha

Add a captcha image on pages that are potential hacking targets. For example you could add captcha to your login page.

 

Well that does it. Happy Coding.

 

Comments
BR's Gravatar I have a noob question that I can't seem to find the answer to anywhere. I need a way to encrypt then decrypt user passwords as people register on my site. I would like to use ecrypt function to do this with generatesecretkey. However, I am unsure where to place the code to do this? If I must use the same key to encrypt and decrypt each password, does that mean I must generate and save a new key for each user who registers on the site. Example: user A registers I encrypt password with generatesitekey A. User B registers I encrypt their password with generatesitekey B. If I had only one key I don't see a way to decrypt everyone's unique password. Where would I store this key? In a DB somewhere, a cookie on the client, etc.? Thanks.
# Posted By BR | 10/23/08 10:41 PM
Sid Maestre's Gravatar @BR

Instead of using encrypt for your password, why not use the hash() function. When you store a password in the database using the hash function, it's more secure. It will be harder for hackers to "decrypt" the password if they gain access to your database. Of course the downside of hashing is that it's one-way and you won't be able to see the user's password. But not seeing your user's password is a GOOD thing. There really isn't a reason for you to see their password.

If a user forgets their password, you won't be able to retrieve their password and email it to them. Instead allow the user to reset their password. I allow users to request a "Password Reset Key". Upon request I generate a random key, hash it, save it to the database and insert the date/time. The user has 24 hours to retrieve the password reset email, click on the link and enter a new password. Of course it could be 4 hours or 24 hours you can decide.

Back to your original question. If you must encrypt and decrypt user passwords, you can place your secret key in the Application.cfc file. Store it in the application or request scope. It will be available for encrypting and decrypting.

#Encrypt(form.password,application.secretkey,'ENCRYPT-TYPE")#

Good Luck!
# Posted By Sid Maestre | 10/24/08 1:34 PM
BR's Gravatar Thanks for the quick reply. I didn't want to use HASH for the simple reason to allow users to see their password in their profile and change it on the fly. But based on your advice I can still implement something that is not too much of a hassle to the user. Everything on the NET suggests using HASH as you have stated so I guess I'll go with the standard. But thanks for clarifying how encrypt works though. Much appreciated.
# Posted By BR | 10/25/08 10:28 PM