Web Security and Encryption - Missing a Middle Ground?
Posted on July 11th, 2008 in Security, Web Development |
It occurs to me that online security is generally either very thorough or non-existent. If a website needs to be secure it uses SSL. If security is not utterly essential, there is often no security used at all - everything is transmitted in plain text. What about the sites that have login forms, sites that take some potentially confidential information from clients, but can’t afford a full SSL certificate.
SSL provides extremely strong encryption and uses a very effective protocol to help with authorization. This protocol makes use of a Certificate Authority - the CA issues the certificate that the server uses in the protocol, and is trusted by the client. It is possible to generate your own certificates, but if a certificate is encountered that has not been issued by a trusted CA a popup message is displayed in the browser window that warns users that the site may not be secure. This feature is vital as it warns users not to enter confidential information (such as credit card details) on a site that is not absolutely secure.
There are, however, sites where absolute security isn’t necessary. SSL certificates cost money. To give you some idea, VeriSign - one of the largest (if not the largest) CAs charges £599 + VAT for their mid-range SSL certificate (Secure Site Pro - 128bit encryption). To be fair, sites such as RapidSSL offer cheaper certificates, but for hobby sites or sites on very limited budgets any price is too much. More and more sites these days require you to sign in to access their full content - I’d bet that most people re-use passwords accross different sites (including for their web-based e-mail?). If this is the case, logging in to a site that doesn’t use SSL could mean that a user’s password is sent across the internet in plain text, which makes it completely vunerable to eavesdropping attacks. If this same password provides access to an e-mail account, the user’s identity could potentially be stolen (an e-mail account can be used to gain access to other sites using the “I’ve forgotten my password” forms).
To me it seems absurd that there isn’t already a mid-level security system, one that uses regular HTTP, that is free but not as secure as SSL. Even a system that didn’t bother encrypting pages - that only encrypted form data would be useful. For the time being, I will present the way that I prevent passwords from being sent in plaintext in login forms. (Note: this is not completely secure by any means, and only works with JavaScript-enabled browsers).
This example demonstrates the steps for a login page being displayed and the user logging in using their username and password. A password stored on a server shouldn’t be plaintext, for this example we will assume that an MD5 hash of the password is stored.
- The server generates a random salt and embeds it in some JavaScript code on the page.
- The user fills in the form with their username and password.
- When the form is submitted, some JavaScript code catches the event and pauses the submission.
- The JavaScript code produces the MD5 hash of the user’s password. It then concatenates the hash with the salt provided by the server. An MD5 hash is then produced of the result and submitted in place of the password.
- The server identifies the user by their session and recalls the salt from a session variable. It also produces an MD5 hash of the concatenation of the password hash that is retrieved from the database and the randomly generated salt. If the result of this matches the user’s input, their password is valid.
As I stated before, this is not entirely secure - session cookies can still be stolen, most of the transmission is still plaintext, but it does protect the user’s password from man-in-the-middle and eavesdropping attacks.
11 Responses
A system like you described it doesn’t seem to offer any protection at all. If the server provides some kind of secret, what stops the man-in-the-middle to just intercept the secret and provide his own? To reliably communicate over the Interwebs you need some system that doesn’t need secrets, but uses public keys instead, like SSL does.
One could however switch to a decentralised model, similar to PGP/GnuPG, which provides somewhat less security (you can’t really trust the identity of someone unless the web of trust is really good).
Try looking into HTTP Digest authentication
@Adrian: The system I provided wasn’t meant to replace SSL - a man in the middle attack could replace the secret (the salt), but that would only prevent the user from logging in, it wouldn’t reveal his password to the attacker as the entire string is hashed. This isn’t meant to be a full secure communications system - for that you would need a trusted party (Trent in Bruce Schneier’s terms), it is merely meant to be a secure way of confirming that the user has the correct password without revealing what the password is.
@Queueless: Thanks - I hadn’t really looked at that, it looks fairly similar to what I described. Is it possible to integrate HTTP authentication with a form on a website (rather than the browser displaying a popup)?
I recently did something very similar to this for work. I was writing a web app which would be able to delete certain lock files on a server. These files would always contain a guid, so the hashed contents of a file was enough to identify it.
The page displayed the files you could delete and a password box. When you submit the page, the javascript would find the hmac of the password and the contents of the file you were deleting and submit that instead. No session cookies to be stolen, and it prevents man-in-the-middle attacks (though I was a bit lucky because the same action will never be repeated).
(hmac is basically a combination of hashes (I used sha1) which does a little bit of stuff to make guessing the password harder)
What you’re describing here is basically Digest-MD5, which does protect against passive eavesdropping. However, it provides no protection against a man-in-the-middle attack. When the attacker is in the middle he can simply replace the form page with whatever he wants and send any sensitive data directly to his site.
Now, please don’t take this the wrong way, but you seem to be suffering from a common misconception about SSL. The major benefit of SSL certificates is that they provide a method for validating the identity of a host. Without that validation, the encrypted channel would always be vulnerable to a man-in-the-middle attack, just as your proposed JavaScript scheme is.
@Justin: That’s a fair point about it not being secure against man-in-the-middle attacks - a man-in-the-middle could simply remove the entire security system; all I was saying in my previous comment was that assuming the system was in place, changing the salt wouldn’t give the attacker the password.
When I referred to this not being a replacement to SSL, I meant that it not only doesn’t provide a secure channel, it doesn’t provide any authentication either (as SSL would). As you pointed out, a certificate system involving trusted certificate authorities would be needed to prevent man-in-the-middle attacks.
Can Digest-MD5 be used within a form on a page or does it always produce the browser popup window?
Digest-MD5 is an authentication mechanism supported by the HTTP protocol–meaning you would get the standard HTTP authentication dialog. It also performs the digest directly against the password and nonce, requiring plain text password storage. Between that and the potential issues with browser support, the JavaScript solution is arguably better even though they suffer the same vulnerability to a man-in-the-middle attack.
As an aside, I’ve seen schemes similar to what you proposed. In fact, I’m pretty sure that Yahoo! used a similar scheme at some point. Also, if you’re particularly interested in this topic I’d recommend looking at the clipperz implementation of SRP in JavaScript: http://www.clipperz.com/open_source/javascript_crypto_library
SRP is designed to protect the user’s password even in the event of authentication data at the server being compromised. It’s about the strongest authentication you can get, accepting that any model falls apart if the server can be compromised or impersonated during an authentication sequence.
@Justin: Thanks a lot for that - I’ve still got a lot to learn when it comes to security and cryptography, but I’m reading Bruce Schneier’s book ‘Applied Cryptography’ which has hugely helped me understand cryptographic protocols in general. That clipperz javascript crypto library looks interesting - i’m definitely going to take a look at that.
Digest authentication is not secure - it is a thin protection of your password that basically promotes the secret from being a plaintext P to being the hash H(P). It is trivial for an attacker to create an HTTP request using the digest/hash, or to crack your password using rainbow tables. Which is why no-one really bothers with digest authentication.
Your scheme is subject to MITM attack, which is bad but in general more secure than digest authentication. MITM is an active attack and (generally) harder to achieve than passive sniffing of traffic (which is sufficient to defeat digest authentication).
The other problem with your scheme is that it promotes the hashed password (which is stored by the server) to being a shared secret key - so if the server is compromised then all the secrets required to log on as any user are known.
Schemes like SRP are cryptographically good solutions to this problem. You can also just use a self-signed SSL certificate and publish the fingerprint (in an independent location) so those who care.
FANTASTIC!