Adding login and administrative features to your cfWheels apps has cropped up on the mailing list a few times, so I thought I'd just pull together a simple example for Active Directory / LDAP authentication.

In this particular snippet, I want to establish a user a) has credentials on the server, and b) belongs to a group called 'ContactsDatabaseUsers'.

This method has the benefit of a) not having to store user's passwords in your application database and b) allowing system administrators to control access to the application.

This example assumes you have a login form at /main/login/ which posts params.username and params.password to /main/dologin/

I also would have a local users model where I could add additional application specific options: i.e, when they last logged in, etc. 

This information would then be copied to the session scope. ie. session.currentuser

When the users first login, this local entry needs to be created, or copied to the session scope from the existing entry.

Occasionally I forget clever little things, like using functions as argument values.

Here's a small snippet which I ended up using when doing a blog front page, where I wanted to strip the tags out of the blog body, truncate it to 300 characters, and then add a 'read more' link at the end of the paragraph with an ellipsis.

There's a load of nice little functions in CFWheels for this - stripTags(), truncate() and linkTo().

Here's what the helper in the loop ended up as:

As I'm (hopefully) going to release my first open source project soon, I thought it would be a good time to revisit application security, specifically password hashing, salting and general encryption. If you've not come across Jason Dean's blog, I'd recommend that as a first port of call, as most of what I'm referring to is explained there.

Password security is one of those never ending journeys; you have to assume that it'll never be perfect, and that there's always room for improvement. I'd recently had an idea to improve password hashing a little, which someone might find useful in principle.

Let's take a simple password, like 'myPassword1' (incidentally, if you actually have any passwords like that, please go and get lastpass or password1 immediately and wash your keyboard out with soap).

'myPassword1' stored in a database in plain text is obviously a very, very bad idea. Most people's gut reaction would be to hash it, which at least is one way.

But wait!, let's assume 90% of our users are stupid, or at least, uninformed. If two people have the same password, their hashes will appear identically in the password column. On top of that, if I hash the password again, I'll get exactly the same resultant string. So a hashed (unsalted) password is really not that useful. You could perform a 'rainbow table' attack: password hashes from your database can be compared against a table of known hashes (such the hash for myPassword1), et voila, password revealed.

So the next step is to introduce salting: that is, appending or prepending a unique string to the password to make the resultant hash unique, and make rainbow table attacks much much harder.

This has the advantage that attacks require the salt to even attempt some sort of dictionary/rainbow table attack. Usually the salt is stored alongside the hashed and salted password in the database.

This is the part which I think could be improved by a relatively small step. By storing the salt alongside the password in the users table, we're essentially giving a hacker the necessary ammunition to attempt to compromise the password. Let's make it a little harder. Let's encrypt the salt itself using another key, stored outside the webroot. So I might have a folder called 'auth' on the same level as my 'webroot' or 'html' folder. In there, I'm going to store a text file with a UUID inside. When I want to compare a password hash, I now have to decrypt the salt before I can use it (as I acutally need the salt value, I'm not hashing it, as that's one way) using the key read in via CFFILE outside the webroot.

So why do this? If your database is compromised, you at least have an additional key to the puzzle missing for the attacker: they would have to do both a compromise of the filesystem AND the database to get anywhere. Additionally, you could quickly invalidate all the passwords in your application by deleting/regenerating the 'master key' at a file system level (this also assumes you have a half decent 'forgotten/reset password' feature in your application), which could be useful is you suspect the database and file system to be compromised at any point.

Whilst this is hardly comprehensive explanation, by adding additional layers and parts to the process, we'll hopefully make any attackers lives a little more difficult. Jason Dean adds another step I like looping the hashing process over 1000 times - if you made this number completely arbitary between 1000 and 1500, you'd have another variable the attacker would have to get, and this one would be stored in the source code of the application itself.

So assuming you added all the above measures, you'd have to:

  1. compromise the database (for the password hash, and the encrypted salt),
  2. the source code for the application (to get the number of hashing loops), and
  3. get the facility to navigate outside the (potentially) locked webroot (to get the master key to decrypt the encrypted salt).

So, I was reading up on the Fibonacci sequence the other day, and wondered how long it would take CF to calculate the sequence to a couple of thousand steps, and also how long those numbers ended up becoming.

Consider the following loop:

I immediately hit a few issues. One was scientific notation, which was solved by numberformat(), but the other issue I found was that if I tried to increase the number of loop iterations beyond 1475, I'd get an error simply stating 'For input string: "I"'

Removing the numberformat mask revealed 1.30698922376E+308 as the largest generated number in the sequence, with the remaining rows represented as '1.#INF'.

So, out of curiosity, does anyone know why? Is it simply that Java can't handle larger integers?

Right, following on from part 1...

We should at this point be getting the _emailaddress partial loaded in our form. What I want to do, is be able to add additional email addresses, and get Wheels to update the nested properties appropriately when I submit the form. Oh, I'm assuming you're using jQuery too.

Firstly, a disclaimer. Javascript isn't my strong suit, at all, in any way, whatsoever. The following will undoubtedly be able to be condensed down into something much more efficient. Also, this isn't my javascript - this is unashamedly nicked from Ben Nadel (see http://www.bennadel.com/blog/1375-Ask-Ben-Dynamically-Adding-File-Upload-Fields-To-A-Form-Using-jQuery.htm). Yet again, I find myself standing on the shoulders of giants.

In order to understand what I'm doing, it's probably best to look at the generated code which wheels makes for our email address partial.

As a reminder, here's what the cfWheels code is:

So this creates:

What we want to do is replicate this output on the fly using Javascript, and increment the counter (i.e, all the 1's in the above example).

In order to do this, I need to do a few things. Firstly, I need to make sure I can reference the existing set of email(s), which are loaded when the page loads, then I need to be able to clone this set of fields, incrementing the count as I go, and finally, I need to be able to have appropriate add and remove buttons/handlers to deal with manipulating the DOM itself.

Once that's done, I then can submit the form and do the update: since writing part one, I've come accross a small catch with this approach which requires a extra line or two of code (oh noes!) which I'll get to later.)

Creating theDOM Template

So, in addition to my email address partial, I'm going to create another, called _emailaddressTemplate - Warning, bad code ahead...

So what's going on here? At the top, I've got a template, using Ben's ::field:: references. Underneath I've got the JS to replicate the template and insert it in the appropriate place, and increment the counter.

This partial needs to be include *OUTSIDE* the form: this is important: otherwise these oddly named form fields will get into your params and cause problems.

Also note, I've got an anchor tag with class of .removeemail - this allows me to remove the parent div element onclick, thus removing it from the the form.

Back in my edit.cfm, I'm going to add these includes, and add another anchor tag to add the additional form fields. So it now looks something like this:

So important to note, my DOM template partial is outside the form.

The catch I mentioned earlier comes when updating this: as is stands, I've not got a way of telling wheels which email addresses to delete etc. so when I loaded the contact model in my update function (see part 1), it would update and not replace the nested entries. I've done the following to simply replace them: More disclaimers - I can bet there's something I've missed, or a better way of doing this: cfWheels gurus please do enlighten me!!

My new update() function in Contacts.cfc controller:

This works for me, but as you can see, there's a fair bit of tidying up to be done, especially on the JS end.

 

About

OxAlto Design - ColdFusion and other such web musings.

Categories

Monthly Archives

Links

Tag Cloud

coldfusion web-development internet misc music cfwheels railo drupal vps chchchoir blueprintcss jquery mangoblog flex ipod mac wowza demos flash flickr google hinkseystudio itunesu wallpapers wordpress

Feeds