My readers know I'm not a fan of the CFLOGIN feature in ColdFusion. It's one of the few areas where I've had continuous frustration and disappointment. Since just about everything else in ColdFusion is absolutely dreamy and gives me butterflies in the stomach, I don't mind that much. But I had to share this finding that was sent to me by Tony. His problem was this that users were unable to login even though he knew they were using a proper username and password. He did a bit of debugging and noticed something odd.
Every time a user had a colon in their password, the cflogin scope reported the password as everything before the password. Here is a simple example that demonstrates the issue.
<cflogin> you arent in <cfif isDefined("cflogin")> <cfdump var="#cflogin#"> <cfdump var="#url#"> </cfif> </cflogin>
Run this template and add the following to the URL:
Remember that the cflogin scope is populated when the security framework senses a login attempt. This can be via HTTP Auth, a Form (or URL), and Flash Remoting. The dump though shows a problem:
As you can see, cflogin.password is incorrect. If you tried to pass it to code to do an authentication it would fail. What's odd though is that you can use the value in cfloginuser:
<cflogin> you arent in <cfif isDefined("cflogin")> <cfdump var="#cflogin#"> <cfdump var="#url#"> </cfif> <cfif structKeyExists(url, "login")> <cfloginuser name="ray" password="ray:cf1" roles="foo"> </cfif> </cflogin>
Notice the hard coded cfloginuser. If you set the URL to ?login=youbet, then you get logged in just fine. I did a bit of searching and didn't find anything in Google, but the Wikipedia entry on HTTP auth clearly says:
Before transmission, the user name is appended with a colon and concatenated with the password. The resulting string is encoded with the Base64 algorithm. For example, given the user name Aladdin and password open sesame, the string Aladdin:open sesame is Base64 encoded, resulting in QWxhZGRpbjpvcGVuIHNlc2FtZQ==. The Base64-encoded string is transmitted and decoded by the receiver, resulting in the colon-separated user name and password string.
Well, that would be it, wouldn't it? Now - this doesn't mean you can't use cflogin as a security framework. It just means you can't use the cflogin scope as a means to authenticate. You would have to hard code the access (form.password for example) or force users to pick passwords without colons.
With that said - this is probably not a CFLOGIN bug per se, but probably just a byproduct of the nature of the system as a whole.