6 ms·
Ask YC: Best Practices for User Authentication
Hey,
I'm wondering about the practices about authentication with regard to passwords.
I'm looking to exclude the HTTPS / SSL cert method, which is obviously the most secure method, but it's not completely within reach right now.
What I'm currently looking at is simply a Javascript SHA2 implementation that hashes the password before it is sent to the server. After reading a recent post (http://news.ycombinator.com/item?id=205420), it seems that this implementation isn't the best.
Here's what I got from that:
+----------+ +----------+
+->| SERVER |---------->| CLIENT |
| +----------+ nonce +----------+
| | |
| SESSION["nonce"] = "1234" | SHA(nonce + password)
| |
+------------------------------+
(sorry for ASCII drawing failure)
What is good practice for user password authentication without SSL? (Feel free to yell at me for not using SSL, but I'm currently not able to implement it.)
Thank you.
- jsjenkins168 18y agoAs was pointed out by tptacek, this approach is not secure because the javascript can be rewritten in transit. Also consider that javascript-based hashing will be extremely slow and could interfere with the user experience if the browser bogs down. And IE may show an error that performance is slow on your site. There just is no way around it, the only way to be secure is use SSL to share secrets when you register. From then on you can just transmit an authenticator (stored in a secure cookie) comprised of an expiration timestamp, any identifying user data (like userID), and a non-malleable MAC digest of the expiration and userID. Doesn't protect against replay but it helps to enforce a short expiration for the authenticator. With this approach you'll only need to use SSL for the initial login. This is the best explanation of web authentication I've encountered on the net [PDF]: http://prisms.cs.umass.edu/~kevinfu/papers/webauth_tr.pdf http://prisms.cs.umass.edu/~kevinfu/papers/webauth_tr.pdf
- DaniFong 18y agoDepending on who you are, you could guard against javascript being rewritten by a man in the middle attack by running, say, a greasemonkey script that figures out when a password should be sent and hashing with the server domain automagically, so long as you can cache it locally. In this way, admins could secure clients against having their passwords stolen without any effort on the part of web-app writers, or users. Even a browser, say, Firefox, could do some version of this. Really, digest authentication solves the same problem, but hardly anyone uses it.
- tptacek 18y agoI know you're just trying to add a layer here, but if you think this through, you'll probably see that GreaseMonkey does not win against content-controlled Javascript for its own site. Firefox has had a hard enough time just keeping content-controlled Javascript from breaking into Chrome. As a simple example, note the fact that the "when the password should be sent" signal originates from content-controlled JS, which controls the DOM. Note also that with same-origin out of the picture, the content-controlled JS can choose to send the password whenever it wants.
- DaniFong 18y agoSure, it's not meant to be foolproof. I only wanted sometime to secure the login for the large number of sites taking passwords with plaintext. Right now it's completely a statistics game -- you can just stand outside someone's wireless network capturing packets. If it's insecure or WEP, you'll be able to recover the key, then grepping through with password=_ will eventually give you a password to use on their favorite sites. I do think security is a matter of degree. And currently authentication is but a few removed from wide open.
- tptacek 18y agoThis is why app developers should be using SSL. I have no smart-assed responses to an HTTPS login screen. No ad hoc hashing schemes required.
- DaniFong 18y agoBy the same logic, crackers shouldn't attack anything. But they do.
- tptacek 18y agoI'm not sure I see how that follows. But to reify this a bit, do a little Google research on what the banking industry is dealing with regarding multifactor authentication. Nothing they are trying is working, and they're doing considerably more than Javascript hashing. The schemes being discussed here are being attacked, successfully.
- tlrobinson 18y agoHashing the password on the client with a nonce provided by the server and checking on the server is good for login, but not registration. The server still needs the password (or a hash of the password and a salt) in order to compute the login hash for comparison. The only truly secure way (that I can think of) is some sort of public-key encryption, either SSL or some JavaScript library.
- markbao 18y agoThat's very true. Damnit. Not sure how I'm going to fix that. I've looked into public-key encryption, and unless if I generate a new public and private key for every request to login, replay attacks are still possible.
- DaniFong 18y agoIf you hash the password on the clientside, say, and then use that as the password in your scheme throughout, then you don't need to transmit the password in cleartext, ever.
- tptacek 18y agoThis is a win because, even though you're sending something password-equivalent over the wire, at least you're not exposing a password that's used on other applications?
- DaniFong 18y agoPrecisely. For all the hackers ignoring it, there stands the simple fact: people reuse passwords over and over again, for bank accounts, email, and everything else. I don't know what the stats are, but I'd bet if you randomly query people in, say, your or family, you'll find quite a few. At least I did. So while capturing a password over HTTP and replaying it gives access to someone's karma in a site like this, once you actually know the plaintext password you could, for many people, use it to break into otherwise secure sites (even using SSL), like gmail. This has serious reprecussions. Finding a password over the wire is just like finding password: <something> in a closed drawer. Sure, you don't know what it's for, but were you malicious, you'd be able to try a host of different places.
- jrockway 18y agoYou've basically reimplemented HTTP Digest auth, although not quite as well. The problem with your implementation is that the server needs to know the cleartext password. With digest auth, the server never has the clear password, (only a digest thereof) although it can use the digest to authenticate to other services with the same digest. It doesn't really matter though, since passwords are very insecure and users know that. Nobody is going to give your web app an important password. If they do, and it gets compromised, it's their problem, not yours. (For secure authentication, look at how ssh uses public/private keys. Much better. Compromising the server's password database will never yield the private keys and hence is a complete waste of time for an attacker.) Anyway, I tend to transmit passwords over SSL and then store them in the database hashed with bcrypt (http://search.cpan.org/~zefram/Crypt-Eksblowfish-0.005/lib/Crypt/Eksblowfish/Bcrypt.pm http://search.cpan.org/~zefram/Crypt-Eksblowfish-0.005/lib/C...)
- gommm 18y agoThe problem is that most users are not programmers, are not at all interested in computer security... So, no maybe most people here would not use an important password for yc news... But the average user doesn't think about this and knowing this can you really say that it's there fault for not being educated on computer security? Anyway, since you do the right thing: SSL + bcrypt, good but don't say it's the user problem if the system gets compromised...
- dfranke 18y agoWhat's the difficulty with implementing SSL? If you're not already familiar with it, read the manpage for s_server, which is part of OpenSSL.
- markbao 18y agoNo difficulty in implementing SSL, but I'm a student and don't have much money. Granted, this is a temporary solution until I'm able to get some money together for a dedicated IP and SSL cert.
- dfranke 18y agoYou can do SSL very cheaply these days. GoDaddy has certificates for $15/year. Dreamhost gives you a dedicated IP for an extra $4/month.
- SA 18y agoGiven the fact that how cheap it is these days to get SSL certificates and static IPs I would take the route of SSL rather than going thru this untested (read: not well tested) route of JavaScript encryption. http://www.hitlinkz.com http://www.hitlinkz.com
- swombat 18y agoPlease don't spam your URL, especially not as your signature. That's (very) bad form.
- tptacek 18y agoNo security scheme delivered over Javascript is going to make a difference in a security audit. Your auditor is going to tell your prospective customer that anybody who controls the DNS, routing, the network, ARP, the browser --- or 10 other places --- can rewrite the Javascript in transit. If you can't do SSL, just do plaintext passwords. It means you're being open with your users about the risk.
- huhtenberg 18y agoTechnically speaking, the first thing any decent security auditor will tell you is that certain security mechanism making or "not making a difference" depends solely on a threat model. Challenge-response authentication protects against passive attacks (such as sniffing). Rewriting Javascript in transit implies an active attack scenario. In a majority of cases, yes, the active attacks are a part of a threat model, but there are deployment scenarios where they are not.
- tptacek 18y agoName one.
- brfox 18y agoI'm no expert... but what if just the javascript was served via https? Maybe somebody ought to put an MD5 javascript library on an https server as a public service. Or would js hashing still be vulerable since the man-in-the-middle could change the nonce or something?
- ben_h 18y agoIf you're going to serve Javascript over SSL, you need a full SSL setup including a valid certificate, etc. If you have that, you may as well just serve the login form itself over HTTPS, redirecting back to HTTP after logging the user in, and forget the Javascript altogether.
- ComputerGuru 18y ago
- tptacek 18y agoAlso: any security scheme based off a simple hash function is going to require you to store cleartext passwords on the server side, meaning that any SQL injection vulnerability compromises, say, 10,000 user passwords.
- markbao 18y agoActually, I made a mistake in the diagram. The password will be hashed first, then the sha2(nonce + sha2(password)). Passwords will be stored server-side as sha2(password). Can't update the post now, though.
- boucher 18y agoThis is basically what we do.
- theg 18y agoYour method for storing the passwords server-side is actually not very secure. Hashing the passwords without a unique salt is not a secure way to store them. For one thing, every user with the password of 'secret' will have the same hash in your database. Secondly, if I were to steal all of your password hashes, I would just have to compute sha2 of every 6-8 (or whatever password length you are using) character string. With a 32 character salt, I would have to compute a sha2 of every 38-40 character string, making my job a more time consuming.
- markbao 18y agoThe thing with a salt is that - would you include the salt in the Javascript hashing system? like sha2(nonce + sha2(password + hash)) ? If so, then the salt isn't really that useful - you can then just compute sha2 of 6-8 letters + salt.
- gommm 18y agoThe only usefulness of the salt is if somebody steals your database and uses a rainbow table to try to get the passwords. If you don't have salts for each users, then a pre-generated rainbow table for sha1 based on common passwords is going to be very efficient at getting the passwords for each account. If you use salt however, you are protected from the use of pre-generated tables since the attacker has to brute force all the combinations for each user. If you use sha1 or md5 it's still not too secure since sha1 and md5 are fast to calculate and getting faster with this : http://nsa.unaligned.org/hw.php http://nsa.unaligned.org/hw.php Read http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-need-to-know-about-secure-password-schemes/ http://www.matasano.com/log/958/enough-with-the-rainbow-tabl... from tptacek, it's very informative... Of course, the big problem with the javascript way explained here is that you send sha2(nounce + sha2(password+salt)) This means, that anybody who get access to the database can send sha2(nounce + hash_from_database) So basically in this case using salt in the database prevent people from getting the password too easily (so it sorts protects the attacker from getting a password associated with an email address that he could try later on paypal), but it doesn't protect the account in any way... And for those who think that it's unlikely for anybody to get access to the database, it happened to the reddit guys...
- curiousgeorge 18y agohuh? whatever you do on the client machine you're still open to a man in the middle attack . hashing passwords simply make it more difficult for eavesdroppers to figure out the original password, and keep people from passing potentially sensitive information across the net in cleartext. use SSL for things you need to keep secure, like credit card payments. If you can't set that up, outsource stuff to a payment provider like Paypal until you get your house in order. Otherwise be more clear about your security concerns in your write-up, so people know WHAT you are trying to solve instead of HOW you are trying to solve... something.
- johnm 18y agoIn practical terms, just use HTTPS with rooted certs. It's not expensive for basic usage. And, if you're just doing a for-fun project you can always use self-signed certs. If you want to go deeper down the rabbit hole check out SRP: http://srp.stanford.edu/ http://srp.stanford.edu/ In terms of dealing more securely with data on your server, check out the book, Translucent Databases ( http://www.amazon.com/Translucent-Databases-Peter-Wayner/dp/0967584418 http://www.amazon.com/Translucent-Databases-Peter-Wayner/dp/... )
- tptacek 18y agoStay away from SRP. Browsers don't support it natively, and there are (so far as I can tell) no peer-reviewed libraries for it for the major web stacks. SRP is easy to get wrong.
- johnm 18y agoI did say to use SSL in practice, right? Reading about SRP would help solve much of confusion people seem to be having in many of the discussions going on in this thread.