A website is only as secure as its weakest link. We should assume that an attacker has access to everything that is on the server. To this end, transmitting the password to a server in clear text isn't such a great idea.
It is possible to minimise the chance of a password being intercepted by simply not transmitting it at all, and instead sending a password digest. SHA can be used on the client-side to produce a password digest along with a random nounce to prevent replay attacks.
If the client doesn't have JavaScript, it simply supplies the password (as per what is typical).
This diagram shows the basic of a secure hashing login system, which can be easily implemented.
Client Side
Here is a client using jQuery. The login hash is retrieved from the server using AJAX.
Server Side
The database I am using as an example is for email accounts. It is slightly more complicated than a typical example.
Finally, it is important to remember that this approach is not inherently secure. It is just one option to ensure that password does not travel in clear text. I highly recommend this article by Troy Hunt "Our password hashing has no clothes" which discusses the risk of using SHA for password hashing. I personally recommend using BCrypt.
it is a great example of how security can go wrong. it all starts with the design: since you’re not storing the random hashes on the server you are absolutely open to replay attacks. (because session faking is very easy if you can tap the wire and it isn’t https)
and the worst thing is, that you will get a false sense of security by implementing your solution… :(
@huhawk I agree that there are many attack vectors – the only benefit of this approach is to ensure that the password is not transmitted in clear text. You’d still want to add SSL/TLS on top of this for a secure site. However, even for SSL/TLS secured sites, it concerns me that the password is typically transmitted to the server in clear text. By using a password digest, the password is never transmitted.
Comments
“(rand*255).to_i.chr” should be written as “(rand 255).chr”
but 255 could never be generated either way. you probably wanted
“(rand 256).chr”
Hi Bob – Thanks, I’ve updated the code to include your suggestion.
it is a great example of how security can go wrong. it all starts with the design: since you’re not storing the random hashes on the server you are absolutely open to replay attacks. (because session faking is very easy if you can tap the wire and it isn’t https)
and the worst thing is, that you will get a false sense of security by implementing your solution… :(
@huhawk I agree that there are many attack vectors – the only benefit of this approach is to ensure that the password is not transmitted in clear text. You’d still want to add SSL/TLS on top of this for a secure site. However, even for SSL/TLS secured sites, it concerns me that the password is typically transmitted to the server in clear text. By using a password digest, the password is never transmitted.
What js library are you including?
I don’t get this line of code? password = $.sha1($(‘#password’).val());
@Mike I was using a jQuery SHA1 plugin for this bit of code, I couldn’t find the original source but there appears to be a copy available here.
Leave a comment
Please note, comments must be formatted using Markdown. Links can be enclosed in angle brackets, e.g.
<www.codeotaku.com>
.