Ask HN: Which login method do you use? I'm at the point where I need to implement login capability on my main page. What method do you use? php with a database? cgi against a protected file? Clickpass.com like HN. Or did you roll your own? |
Ask HN: Which login method do you use? I'm at the point where I need to implement login capability on my main page. What method do you use? php with a database? cgi against a protected file? Clickpass.com like HN. Or did you roll your own? |
On registration:
- Ask for username and password (do form validation, ie passwords match, xss clean, etc). toLowercase() the login.
- Create a hash of some type for the password. This becomes used in the database, and again on login. If you're not worried about security, md5 your password, store it in the db. Otherwise, look up a salt hash.
- I typically log the user out and then require them to log in and create a session after they registered.
On login
- Ask for username and password, toLowercase() the login when checking
- Run the same md5 or salt hash against the password, check if the # of rows in the database is > 0, if it is, log the person in and give them a session with a value of "is_logged_in" to true or something similar. Also pull the database user_id or e-mail and use that to remember which user you're dealing with.
- If the # of rows found in database is == 0 (where the login and pass equal those from your post variables), the login failed
http://www.matasano.com/log/958/enough-with-the-rainbow-tabl...
I'd personally advise: Use a respected library or at least an MD5 or SHA1 approach with a strong salt. There are better ways that you should consider (link), especially if you're writing an authentication package for reuse by others.
+ Server has your passwords stored as sha1(password+salt(password)). salt function isn't secret (eg. reverse the text)
- Client visits login page
- Website generates random token. Then sends back HTML with the random token
- Client generates passresponse = sha1(token + sha1(password + salt(password)))
- Client sends the passresponse, token, and username back
- Website checks for existence of token, removes it, then computes it's own sha1(token + password_hash_from_db) and checks against the sent passresponse.
This way the password is never sent in clear text. Unlike HTTP authentication, this works nicely with html forms since you can do all the crypt in js. Then again, this might be a bit overkill... and using SSL is probably a better option.
Just sharing another solution.
* First, because no browser bakes this crypto protocol in, you have to deliver it over Javascript. The protocol basically stipulates that you don't have SSL/TLS. So all you've done is move the goalposts. No matter what kind of dance you do (for instance: Meebo actually delivers a JS implementation of RSA!), the action is now in the JS delivery, which is trivially compromised.
* Second, secure authentication schemes aren't vulnerable to trivial dictionary attacks. This one is: the attacker is stipulated to have access to your traffic. She sees the nonce the server sends and the hash the client responds with. She can solve for the password by (very fast) brute force against a wordlist.
I agree with your second point, a eavesdropped can use a dictionary attack. It makes it just a tiny bit harder for them since they need to generate their own cleartext-crypttext and cannot use a pregenerated table.
I am curious, is there a better way to do this (other than SSL or using RSA)
This is the best strategy for us because it allows us to offer a wide array of services running through our accounts, using out of the box software..
We can tie the forums into LDAP without writing our own, as well as our internal Jabber server, etc.
Once login has completed, we give the user a 128-bit sessionID, which we use for all further communication, until their session expires.
Anyway, if you don't use a nonce per user or a time consuming hashing method, then all tptacek's comments apply. His link in http://news.ycombinator.com/item?id=576021 is worth your time.
It seems pretty straightforward (hash pass, place on server, and check against), but I need an easy way to compute an SHA hash in-browser, so the server doesn't have to receive the pass in plaintext.
Anyone know of a way to do it with Struts/JSP, or even JS if its not too slow?
* The hash you send will probably be password-equivalent; losing it to an attacker is just as bad as losing the password.
* If you're delivering the JS to generate the hash over HTTP, you have exactly the same threat model as with plaintext passwords (attackers will just subst a script that sends the raw password).
* If you have working HTTPS, you already have optimal communications security; just send the password.
* Even if you came up with a challenge-response protocol to make the hash non-replayable, the exchange itself would be vulnerable to a trivial dictionary attack.
Don't bother with this idea. Move on to something that will add real value to your app.
apache has modules to hook it up to just about any backend; it's supported by all browsers, and it's easy to automate against.
I would be interested in knowing why more people don't use it.
You can fail certain formal security audits for using HTTP authentication.
hm. I know you can logout by going to https://username:boguspassword@thesiteyouarelogingoutfrom.co... but that will ask you to re-input your password, usually, making it unsuitable for a 'logout' button usually, I think. I wonder if there is a js workaround for that.
I always try new sites if I can get in with existing authentication - and I don't always if I need to register. So it depends how much you care about uptake.
In the third sentence, take the "or RSA" out. There's no way to get a browser to safely do RSA authentication without SSL.
I have good news for you. The answer to this problem doesn't involve complex technology. What security practitioners are going to recommend to you is, just put up a login page, and send usernames and passwords. I have just released you from having to waste time and energy thinking about this.
I really like http auth because it's a system level solution, and I'm the computer janitor; I know where the problems with http auth are without wondering if the dev who wrote the webapp made a mistake or not.
SHA1+"strong salt" is extremely weak. It mitigates only one attack, which every respected authentication system has been invulnerable to since the '70s. I blame Microsoft for reviving rainbow table lore, but still, thorax. Come on.
First and foremost, don't write the password handling yourself if you can avoid it. If you do it yourself, I'm only firing the developers who put the password in plain text, and I'm not even going to give grief to the ones who at least use a rainbow-dodging salt and hash (like what most major web frameworks include by default for user auth management). I.e., if they use django defaults or Code Igniter defaults, then they're not in trouble.
Any senior engineers on the team are going to get some whining from me if the framework supports crypt/bcrypt and they didn't enable that, but if they forgot and the site launched without it, I'm not going to die.
It the team is making an authentication package for a web framework or especially for a native framework, they need to consider heavily using bcrypt (or other state-of-the-art approaches) for password handling unless there's some major compelling reason we cannot or should not.
What I'm trying to be is realistic and give the guy a side that's non-religious.
I agree with you as a hacker, but on the practical side, no coding decision is all-or-nothing with me.
If you're a new developer and have read this far and want to know where to find decent bcrypt packages for your favorite language, Google's AWT page has a good explanation and handy links to those (scroll down):
http://code.google.com/p/google-web-toolkit-incubator/wiki/L...
Also here's instructions for using crypt with Django auth:
http://docs.djangoproject.com/en/dev/topics/auth/#changing-p...
First, we don't have pages and pages of comments and discussions because the topic isn't cut-and-dry. The topic is cut-and-dry. It just takes 5-10 round trips to explain to someone why clientside Javascript crypto is a bad idea.
Second, I agree with you. I'm not firing someone for using SHA1+nonce. But I will bitch if you recommend it, because even though it's not a game-over mistake, it's still a mistake.
But I suppose that if you are using https, you get most of the advantages of digest anyhow.
Lets say you can crack the average user account with 40,000 hits from a dictionary attack (I imagine most passwords fall much faster) if each lookup takes 50ms, 20 lookups a second, it'll take around 30 minutes of cpu time to crack each password. assuming a reasonable-sized botnet, that's not much.
(1) Not only are rainbow tables avoidable, but they've been trivially avoidable since Unix crypt(3) was invented in the '70s. The only way you can become susceptable to them is if you make the mistake of designing your own scheme. So don't do that.
(2) There's a reason that no mainstream consumer application actually does this: as soon as you lock a normal user out of their account for an hour, you probably lose the user forever. Ok, there are two reasons: this technique doesn't add any security. Anybody nuts enough to brute-force your login page has as many IPs as they want. But that's not how they do it.
(3) People get to access password hashes as soon as you mess up a single database query. The idea behind storing safe hashes is to prevent your stupid mistakes from screwing over every one of your users. The stupidest people of all are the ones who assume they aren't going to make stupid mistakes.
You are right. Use whatever auth system which is available.
I think it's fine if you block IPs after they've hit a fail threshold for logins. Or at least freeze the account for a certain period of time (see failed iPhone login attempts).
I agree with you. People talk about this stupid hashing thing far, far too much. Especially because there's already a "right answer". Just use whichever auth plugin is most popular and provides bcrypt.
Can we talk about the real world, now? The reason Microsoft is driving modern offensive computing researchers nuts isn't that they got rid of the "stupid errors"; it's that they figured out how to make the runtime mitigate those errors with ASLR, NX, safe exceptions, and checked heaps.
In the real world --- and I am speaking from bitter and recent experience with very, very, very smart clients here --- you should assume you are going to make stupid mistakes, and do everything you can reasonably do to keep those mistakes from totally screwing over your customers.
I don't know, it seems to work pretty well for Microsoft
I guess you could go after the OS or the web server, but I was under the impression you were talking about stupid mistakes from the web developer, not the developers of the OS or web server.
The point of adaptive hashing is that doubling the cost of the hash on the serverside adds negligable overall cost, but doubling the cost of the hash on the attacker's side doubles their cost. This is not a complicated tradeoff.
the attacker can check one word from her dictionary in the same amount of time it takes you to authenticate one user for one page.
if you make that check take longer than 50ms, it will start slowing down your webapp.
at 50ms, an attacker can check 40,000 words in around half an hour.
you can double that to 100ms, but at that point you are starting to slow down page loads, and it's still only taking the attacker an hour to run through that dictionary.
(26 + 26 + 10) ^ 6 = 56,800,235,584 combinations
searching half of that would be about 28 billion combinations. At 50ms each, that would take 388,888 hours, or 44.36 years.
[Edit] I regret even conceding this point. Even if you use basic auth, the tradeoff here is not complicated.
But most passwords are not randomly generated. Most passwords are dictionary words, or two dictionary words. You don't need to search the hash space; you only need to search the password space, and if everyone uses the name of their dog, well, that's not a very large space.
http://www.schneier.com/blog/archives/2006/12/realworld_pass...
but my point is that passwords are a lot less secure than they sound if you just add up the characters. And most hash functions take a whole lot less than 50ms of cpu time to calculate. Bcrypt does look pretty cool in it's ability to slow down brute force attacks. It does still require a minimum amount of entropy in the user passwords, though.