Yesterday I talked about securing stored passwords in a database. That is helpful in preventing an attacker from reversing user’s password information assuming they got access to your database. But what good is protecting that information if your users login by passing their username/passwords over plaintext.
Now this whole process is assuming you use email address as the login identifier(otherwise just swap email for username or whatever).
Let’s start by remembering the secured password method in the database from yesterday:
md5(lowercase_email + md5(password))
To protect your users from having their password sent in plaintext, the best method is to hash the value prior to submitting. Since we are taking in the email address and password as login data, we can actually generate this hash in JavaScript and send only the result instead of the password. We never have to pass the password at any point.
While this method is good, it’s not perfect. Any decent attacker could perform a simple replay attack to authenticate against our application. A quick fix for this would be to add a nonce (number used once).
Each login attempt should be preceded by a randomly generated nonce variable (usually 32 alpha-numeric characters) that is stored in Session data as well as user-side form data. With this, the JavaScript executed on login can also perform this:
md5(nonce + password_hash)
The password hash is referring to the secured password method mentioned above. This one-time hash can then be performed on the server side (as the nonce is saved in Session data) and the values compared. Since a new nonce is generated each page load, reply attacks are impossible and your user can login over unsecure channels without a problem.

