My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Thursday, January 18, 2007

JavaScript Unobtrusive Security Form

In some cases JavaScript should be used to add more security during a client/servr interaction.

Paul Johnston knows this and tha's why He created md5 and sha1 hashing JavaScript implemntations.

You can choose to send just hashed form variables, to be sure, for example, that recieved stirngs are valid hash and they are present on db (removing sql injections problems).

You could even create special hashed strings too, to forget "man in the middle" problems, using a salt that will be generated and verified from server side code.

This hashed value could make your password more secure, requiring a kind of brute force that will be quite hard to do.

// man in the middle found the salt and the logging string
$try = 12345;
if(hash($salt.hash($try)))
echo 'Passwrod or collision found: '.$try;
else {
$try = 12346;
if(hash($salt.hash($try)))
// ... and again, again ..
// every time with a double hashed string ( slower than a single :D )
}


At the same time, this salt creates a collisions free hashed string, then a brute force operation should not be used to login in a form like this one because new salt , hashed with collision, will not produce a compatible authorizzation hashed string (or better, it's really difficult that a collision, hashed with a different string, will produce another collision).

This form is absolutely WAI-AAA WatchFire approved, valid W3C XHTML 1.1 and valid W3 CSS.
It's unobtrusive, works without JavaScript too (in a less secure way) and SecurityForm JavaScript function should be used in every kind of form, just modifing form and inputs id as You want.

This is a basic php example page, compatible with PHP 4.3 or 5 or 5.2, that shows how You should "drive correctly" login operation.

I hope code description is enought to understand this kind of form and I suggest to use sha1 instead of md5 (better security).

This is a short description:

  1. Client verify user and pass, if these are not empty call form.action page to recieve a new salt ($salt = uniqid(rand(), true)) sending just userName

  2. Server generates a new salt then it saves them on a simple table adding userName and time() so it sends them as SecurityForm onload callback

  3. Client recieves this new uniq string and generates a logging variable

    logging = choosedHash(salt + choosedHash(userPassword))

    and redirects client to authentication page sending uniqid recieved from server, userName and loging

  4. Server verify that salt table contains recieved salt and verify if found userName is the same of GET value, then verify that logging is a valid authorizzation string:

    // example query
    $query = 'SELECT * FROM user_list WHERE user = $user AND MD5(CONCAT($salt, pass)) = $logging';

    where pass is just hashed during registration

  5. server removes recieved salt from table and other salts with expire less than time() - 30 seconds



... and that's all.
Are You sure, now, that your user with JS enabled are a bit more protected ? :-)
(of course, SSL is absolutely the best way to "ensure privacy" ... but You could implement this kind of form with SSL too)


What about compatibility list ?
Well, every JavaScript compatible browser, starting from IE 5 and every JavaScript disabled or uncompatible browser too.

No comments: