CFLogin Security Considerations
By Pete Freitag
If you use the cflogin
tag to manage authentication you should consider setting loginstorage="session"
in your Application.cfc
or Application.cfm
file for better security.
The default loginstorage
is "cookie"
, when you use this storage a cookie is created called CFAUTHORIZATION_app_name
, where app_name
is the name of your ColdFusion application. The contents of this cookie will be a base64 encoded string of the following:
username:password:app_name
So the actual value of the above would be:
dXNlcm5hbWU6cGFzc3dvcmQ6YXBwX25hbWU=
Now as you know Base64 is not encryption, it is an encoding that is reversible. That means that the password that you give to the cfloginuser
tag is sent in plain text on every request that isn't over SSL.
Now many people actually set the password attribute to cflogin
to be an empty string, or the same value for every user. I have seen some security professionals even recommend this (the reasoning being that you don't want the actual password in memory).
Let me explain why it is a bad practice to set the same cfloginuser
password for every user. Suppose you have the following code:
<cfloginuser name="#cflogin.name#" password="" roles="administrator">
Now suppose I want to login as the user admin
, and your application name is app_name
, I simply need to set the following cookie in my browser:
CFAUTHORIZATION_app_name=YWRtaW46OmFwcF9uYW1l
When you have loginstorage="session"
the cookie you just set will be ignored (tested on CF8). A session variable called CFAUTHORIZATION_app_name
is used instead, and there should be no way to manipulate the value remotely.
So if you want to continue using loginstorage="cookie"
you should use the following guidelines:
- Make sure the password value of
cfloginuser
, is not the actual password - Make sure the password value is different for each user and not predictable. A good practice may be to use a salted hash of the actual password.
Considerations for Clustered Servers
If you are on a clustered environment you need to use sticky sessions, or session replication in order for loginstorage="session"
to work without requiring the user to re authenticate.
CFLogin Security Considerations was first published on December 10, 2009.
If you like reading about coldfusion, security, cflogin, cfloginuser, cookies, or sessions then you might also like:
- Client Variable Cookie CFGLOBALS Includes Session Ids
- J2EE Session Cookies on ColdFusion / JRun
- ColdFusion Summit 2024 Slides: 20 ways to secure CF
- Latest ColdFusion Security Updates - December 2024
The Fixinator Code Security Scanner for ColdFusion & CFML is an easy to use security tool that every CF developer can use. It can also easily integrate into CI for automatic scanning on every commit.
Try Fixinator
CFBreak
The weekly newsletter for the CFML Community
Comments
We are trying to use LoginStorage="session" along with J2EE session management for improved security. Is this what you recommend? Unfortunately, I'm not sure if this is the related or not, but we are experiencing the issues described here: http://mrmx.blogspot.com/2006/08/cflogin-strangeness.html
I can't seem to find an explanation or solution for why this is happening! Have you seen this before and do you or anyone else have a solution that will keep the application secure...and working...using CFLOGIN?
Yes I have seen some strangeness related to this as well. Two things you need to do are:
1) Add some logic *before* cflogin, that does something like cfif IsUserLoggedIn() AND NOT StructKeyExists(session, "userid") then cflogout
2) Make sure that the cfloginuser does not specify the clear text password, hash it.
Let me know if your problems persist after making those changes.
What seems to be happening is that when I close the browser without logging out, and I reopen the browser, there is initially no cfauthorization variable, and I'm correctly displayed the login page.
<cflogin>
<cfif NOT isDefined("cflogin")>
.....LOGIN PAGE INCLUDED
<cfabort />
<!--- found the username and password fields in the cflogin struct --->
<cfelse>
<cfdump var="#cflogin#">
I fill out the login form, I see the username and password submission via form variables, but somehow I'm getting a cfauthorization value back from cflogin without it actually processing any of the code within cflogin (at least that I can tell from my debugging statements.
Since it seems to be somehow bypassing the logic of the cflogin, my session variables are never set, and I never see a display for my dump of the cflogin which is in the "else" clause.
2) I am not sure what you mean here, but this is what I specify after the user has been authenticated against the DB:
<cfloginuser
name="#cflogin.name#"
password="#cflogin.password#"
roles="user" />
Thanks for the assistance!
<cfloginuser name="#cflogin.name#" password="#Hash(cflogin.password, "sha")#" roles="user" />
Restart the server, and clear your cookies as well.
Can you explain the logic of why this works?
The cflogin loginstorage setting only accepts "session" or "cookie" as possible values.