Should the password field be unique? - security

In light of the recent Gawker Media password leak, I've realized that many users share the same passwords. To help encourage stronger passwords, would it be helpful if passwords are constrained to be unique among all users?
One immediate downside I could think of (besides account creation performance?) is being able to know that someone is using a given string as a password. This knowledge, combined with a list of users, could be quite dangerous.
Is there a way to mitigate that downside while retaining the alleged benefits of not allowing repeat passwords?
It's kind of like the XKCD kick bot where you aren't allowed to repeat short, unoriginal sentences like "yah" or "lol".
Edit^2: I thought you could unique-ify against a hash, but as someone pointed out, with varying salts, this would not have the intended effect. Good eye!

absolutely not.
It is critical that no information about passwords be available to users outside the system. If they can easy guess which passwords are in use, by discovering that a password is unavailable, then they can use those passwords on known usernames and get a good shot at gaining access.
An alternative is to find some kind of common passwords database, and prevent any user from using them.

eeeuh
I might be misreading your question, but I hope you do not store the actual password?
You should hash the password with a random salt. That way, there is no way for you to ever tell if one or more users have the same password.
If your systems, in any way, allows you to determine if two or more users have the same password, you are storing the passwords the wrong way.

I would suggest the follwing as you have already mentioned the disadvantage of using "unique# passwords for all
Educate the user's about strong password.
Ask user's to change password regularly.
Keep a "Password strength" meter while they type in the password.

Really don’t
As long as you have salts, the password won’t be stored the same way anyway.
If you want to ensure password security:
Pick a good hash (sha256, blowfish, etc.)
Use salts
Snap-in a password meter with a minimum threshold
A lot of those can be bundled with wordlists
Check out a post I made about it on reddit:
http://www.reddit.com/r/netsec/comments/ektb8/in_the_light_of_recent_gawker_breakout_lets_talk/

If password management is done correctly, the only person who should know their password is the user who created it in the first place. In my web sites, I never store the password in any form. I store a cryptographic hash (SHA-1 or some variant) of that password that is manipulated with some sort of unique "salt" padding. Essentially if two people did have unique passwords, there would be no way to tell.
Most of the passwords on that link you gave are all easily guessed dictionary passwords. Very weak, and easy to brute force. They would all be unallowed by any system with rudimentary password checking.

Related

Store passwords safely but determine same passwords

I have legacy browser game which historicaly uses simple hashing function for password storage. I know that it' far from ideal. However time has proven that most of the cheaters (multiaccounts) use same password for all of fake accounts.
In update of my game I want to store passwords more safely. I already know, that passwords should by randomly salted, hashed by safe algorithms etc. That's all nice.
But is there any way, how to store passwords properly and determine that two (or more) users use same password? I don't want to know the password. I don't want to be able to search by password. I only need to tell, that suspect users A, B and C use same one.
Thanks.
If you store them correctly - no. This is one of the points of a proper password storage.
You could have very long passwords, beyond what is available on rainbow tables (not sure about the current state of the art, but it used to be 10 or 12 characters) and not salt them. In this case two passwords would have the same hash. This is a very bad idea (but a solution nevertheless) - if your passwords leak someone may be able to guess them indirectly (xkcd reference).
You may also look at homomorphic encryption, but this is in the realm of science fiction for now.
Well, if you use salt + hashing, you have all the salts as plain text. When a user enters a password, before storing/verifying it, you can hash it with all the salts available and see if you get the corresponding existing hash. :)
The obvious problem with this is that if you are doing it properly with bcrypt or pbkdf2 for hashing, this would be very slow - that's kind of the point in these functions.
I don't think there is any other way you can tell whether two passwords are the same - you need at least one of them plain text, which is only when the user enters it. And then you want to remove it from memory asap, which contradicts doing all these calculations with the plain text password in memory.
This will reduce the security of all passwords somewhat, since it leaks information about when two users have the same password. Even so, it is a workable trade-off and is straightforward to secure within that restriction.
The short answer is: use the same salt for all the passwords, but make that salt unique to your site.
Now the long answer:
First, to describe a standard and appropriate way to handle passwords. I'll get to the differences for you afterwards. (You may know all of this already, but it's worth restating.)
Start with a decent key-stretching algorithm, such as PBKDF2 (there are others, some even better, but PBKDF2 is ubiquitous and sufficient for most uses). Select a number of iterations depending on what is client-side environment is involved. For JavaScript, you'll want something like 1k-4k iterations. For languages with faster math, you can use 10k-100k.
The key stretcher will need a salt. I'll talk about the salt in a moment.
The client sends the password to the server. The server applies a fast hash (SHA-256 is nice) and compares that to the stored hash. (For setting the password, the server does the same thing; it accepts a PBKDF2 hash, applies SHA-256, and then stores it.)
All that is standard stuff. The question is the salt. The best salt is random, but no good for this. The second-best salt is built from service_id+user_id (i.e. use a unique identifier for the service and concatenate the username). Both of these make sure that every user's password hash is unique, even if their passwords are identical. But you don't want that.
So now finally to the core of your question. You want to use a per-service, but not per-user, static salt. So something like "com.example.mygreatapp" (obviously don't use that actual string; use a string based on your app). With a constant salt, all passwords on your service that are the same will stretch (PBKDF2) and hash (SHA256) to the same value and you can compare them without having any idea what the actual password is. But if your password database is stolen, attackers cannot compare the hashes in it to hashes in other sites' databases, even if they use the same algorithm (because they'll have a different salt).
The disadvantage of this scheme is exactly its goal: if two people on your site have the same password and an attacker steals your database and knows the password of one user, they know the password of the other user, too. That's the trade-off.

What is the need for a strong password?

Now a days each and every website recommend or force us to use a strong password. Every website is most likely that they hash the password and store it in their database then what is the need for strong password if they are hashing the password or why is it required in first place. Is it the same with salted hashing also?
Because hackers try word lists and find out if they hash to the same value as stored in the database.
Weak passwords will be broken quickly, especially if no salt is used meaning that rainbow tables exist that allow lookups of the hash to find the password directly.
There is also the the threat of online attacks. e.g. an attacker trying every account against a web service login to see if they have password1, abc123, baseball, etc.
If you want a convenient way of having strong and unique passwords on every site you use, use something like https://lastpass.com
The reason for a strong password is because simple passwords can be more easily "unhashed" than a strong one. The larger character sets used in the password, and the longer the password it is, the harder it is to crack. Take a look at these videos as there is way too much information to discuss here:
https://www.youtube.com/watch?v=7U-RbOKanYs
https://www.youtube.com/watch?v=3NjQ9b3pgIg

Is there any advantage to re-hashing stored passwords at login time?

I'm in the process of updating several projects from using various insecure/horribly insecure MD5-based password hashes. I'm now at least somewhat better informed on best practices, but I still wonder if I'm doing something wrong. I haven't seen the specific process I'm implementing used elsewhere, but at least one SO user seems to want to do something similar. In my case:
Password hashes are generated using bcrypt. (Since the proper options seem to be bcrypt, scrypt, or pbkdf2 and bcrypt was most easily accessible to me in PHP.)
A different, random, salt is used for each hash. (To prevent attackers from generating a custom rainbow table calculated with a single, static salt.)
The hash, algorithm settings, and salt are stored together. (Since that's what PHP's crypt function give me for the hash value.)
After a successful login, the hash is re-calculated with a new random salt.
It's that last step that I'm wondering about. My intention here to to allow updates to the hashing algorithm as time passes so users who regularly log in will have their passwords stored in the most secure format available.
My questions are:
Is this a waste of time?
Are there any dangers in doing this?
UPDATE
Re delnan's comment : If you are re-hashing the already hashed password, don't -- You never know what vulnerabilities may occur and be found in chaining up hashes. Obviously the other side of that is you need to compute the entire hash-chain every time you validate the user secret -- so just re-hash the cleartext.
ORIGINAL
I upvoted halfway through reading. It seems like you're someone who's asking the right kind of questions to be doing this kind of work.
Not a waste of time.
There are always dangers. Someone could obtain your users' passwords by torture or, more likely, social engineering. Someone could have access to vast resources and along with your shadow password file still manage to crack the passwords. Someone could compromise your server secretly insert a trojan that intercepts the users cleartext passwords at successful login.
So there is no guarantee of perfect security. Ever. But I'm sure you know that already. Which is why I'd like to add only one thing:
Encourage users to choose hard to crack passwords.
And, strictly speaking, if your only reason for rehashing at every login is so that passwords are always stored using the latest update then yes -- your method IS a waste of time, assuming you will not be updating your algorithm at every user's login. So there will be rehashes which use the same algorithm and (presumed) security for two logins in a row. A waste of a few clock cycles on rehashing. Strictly speaking it's not optimized. Why not just include an algo version in your password store, and at login rehash if the system algo is newer than the user's hash algo.
UDPATE
Sorry. Completely missed your point about the use of newer algo's. This is a good thing. :-) But as stated in my original answer below when the algo stays the same it is useless.
ORIGINAL
Rehashing passwords is useless, because if an attacker has already got hold of the hash you aren't preventing anything.
Consider the following:
I am a user on your site with the hash: 1234567890.
Some attacker gets hold of that hash.
I log in again and the hash is changed.
The attacker doesn't care the hash changes because he only needs one hash to try to break.
So nothing has been prevented. The attacker still has the hash and can still try to break it. A possible attacker is only interested in the final result (the password) and not in the hashes.
If someone gain access to the hash changing it every time will not help at all unless the person has access to every update and willingly start over. this isn't going to happen and if it did you would have a much bigger problem then that.
No there is no danger in it only waste of server resources.
Actually, it prevent novice cookie attacker to copy cookie into his browser just to impersonate...so if the owner later login, with a changed hash, it will log the attacker out thereby reducing havoc on the user account.

Security of a password-only login?

I'm working on an admin page in PHP in which a user system seems like overkill. I was thinking of just requiring one password to access the admin page, but I'm not sure if would be safe to do so. I can't see any specific security problems that this might pose, can anyone else think of any?
Edit: By "a user system is overkill" I meant that there is not likely to be more than one user.
Complexity of the passwords aside, there are two problems:
The passwords must be unique now
If you have user+pass, users can have the same password. Under your model, they all must have a unique one.
Limited tracability
A good reason for user accounts to see who does what. You remove this, a little, with a general password as you need to assume, again, a one-to-one matching between them, and users. This may or may not be an issue.
For some of my admin pages, I don't really have a "user" so much as I have two tokens that need to be entered (because I'm the only admin).
For general people signing up, though, and if the password is entered by them, this is not an appropriate plan. If it's just for your admin pages for you, and you generate passwords of an appropriate complexity, life will be good.
It suffers from the same issues as a shared login, making it impossible to revoke for a specific user (if someone leaves, a users computer is compromised, etc), along with the issue of being way more open to brute force attacks (as mentioned by others).
For something simple, that doesn't seem to need a full fledged user/pass system, why not use HTTP Auth built into the server? Easy to setup, doesn't need to be shared, but would require no extra code on the admin script.
To sum up what others have said: Fine as long as the password is not simple, but more vulnerable to brute-force attacks.
Solution: You can enforce a password-complexity policy, and you can throttle further login attempts - get it wrong once, next login is artificially slowed 4 seconds. Get it wrong again, 8 seconds, and so on.
Option: Use two fields - username and password - but make the user also just a static value, like the password. Twice the guessing, twice the effort, twice the security (and twice the hassle for users..)
You could actually throw in a CAPTCHA. That would thwart brute-force attacks pretty well.
There is no problems if your admins wouldn't use simple passwords, like 1234567.
I, have the opinion that having a single password makes the system MORE secure (not less), as long as both the password and system are secure.
The reason is that when you have several users, it just takes one of them with a bad password to be the "weak link in the chain"
That said, nothing wrong with it as long as essential security measures are in place - and keep in mind brute forcing is easier (so make sure it's impossible/ineffective)
I would think that for your admin page (one would think the most secure page) that you would want very tight security?
If your "admin" user has a "hard to discover" username and that is paired with a very secure password I would think that this would be a better system.
Ideally I think you would want to have a complex username and password:
e.g.
Username: e4t_Gjw3#gp
Password: q!-gr7cBFL045$bd
Update: based on the comments I thought I would elaborate on why user+pass is more secure than a pass of "e4t_Gjw3#gpq!-gr7cBFL045$bd".
Having both a username and a password doesn't double the security, it does much more than that.
Pretend that usernames and passwords are both 3 characters (from A-Z) no case-sensitivity.
To guess a password, using brute force, you would need up to: 26x26x26 = 17,576 tries.
To guess just a username, same conditions: 26x26x26 = 17,576 tries.
If you had to guess both but they didn't have to match it would be 17,576x2 = 35,152.
However, if you have to guess the username AND find the matching password it is more like:
17,576 usernames * 17,576 passwords = 308,915,776
Of course if you have up to 16 character usernames (using case-sensitivity, numbers, punctuation etc.) and the same for passwords, the number of possibilities is Insanely Huge and thus... secure.
Update2: I seem to have missed typing the key bit of info I was trying to relay in my update. In most systems I've seen or built, the username and password fields have a size restriction built into the SQL columns of 32, or 40, or X characters. In the ones I've seen where there is just a pass column, the size isn't typically doubled to 64, or 80 chars.
Obviously the pass-only column, and set value can be doubled in length to account for the lack of username - but I have rarely if at all seen this done.
As Jake said, there are many reasons not to do this but it depends on what your application is doing. You need to do enough to put amateur hackers off. Make sure the admin use a strong password - 10 digits, with at least one capital and one symbol or something like that.
Most security experts would still frown on this though.
Password only + Captcha is ideal, Captcha would automatically implement rate-limiting and a strong password will make it secure.

Is the password weak under dictionary attack

Thanks for looking. All sincerely helpful answers are voted up.
I use a password strength meter to let the user know how strong the password they've chosen is. But this password checker obviously doesn't cover how weak under a dictionary attack the password is. How can I check for that, and is it worth it?
Also my regular password checker runs initially with javascript in the browser (no transmission required). If I want to check for dictionary attack weakness, I'd have to transmit it to a script. My understanding is that I shouldn't transmit it in the clear.
Can someone help me sort this out. How do I check the password isn't weak under a dictionary attack and how do I encrypt it before transmitting to my script?
Extra info:
Why do I think I need the dictionary attack check in addition to the regular password meter? As some of you have pointed out, users can choose passwords like P#ssword or Yellow12. But most password strength checkers I've come across will treat this as a good password. At least I'm using Yet Another Password Meter and it does (and I actually think it's one of the better password checkers.) If anyone knows of a stronger password checker, please mention it, but only if you know for sure based on experience that it's stronger ;)
But my question really is: how do I conduct a dictionary attack check on the password? I read somewhere that it's done against the hash, but where do I do the search? Once I find out how to do it, I will then decide whether it's worth it or not.
thanks to everyone who's helped out so far :)
Opinions are going to vary and some people will say that checking for dictionary words is important. I disagree and instead favor requiring different cases of letters, numbers and special characters like !##$%^&*()_-=+. Obviously passwords should be case sensitive.
Dictionary attacks are much less likely to succeed with the presence of numbers and special characters. Lets say that there are 1000 common passwords. Now with the addition of a required upper case letter and special character lets assume the user is "lazy" and they choose to make the first letter capital and add a special character to the end. That 1000 sized dictionary is now over 30,000.
Additionally there should be account lockouts in place to avoid dictionary attacks. And possibly a throttle on how often an IP address can attempt to login depending on your application.
There may still be a case to avoid some very common passwords while running your script. I would for example not allow the word password p#ssword or any variation of password.
Edit: A captcha, while hated by most (including me) may be appropriate as well after a few failed logins to avoid brute force login attempts.
I'm coming to this question later than the others, and I'm surprised that no-one has pointed out that a dictionary check might not be exhaustive. At least no-one has said it in so many words.
I think you need a large dictionary, where each entry is hashed and compared to the hashed password. This will allow you to say the user's chosen password is not in your dictionary, but how will you be sure it's complete?
Obviously, you can't be sure. Do you include foreign words? Technical words?
Do password crackers have access to better dictionaries?
I think all you can do is advise users how to create a good password — show them a few examples — but let it be their choice.
And do the SSL thing.
One additional point - if you control the site, you can stop dictionary attacks by limiting the number of times a user can try a user/pass.
It is great you want your users to have better passwords and you should continue in that direction but a better solution for the dictionary/brute force attack would be an exponential backoff solution to failed login attempts. No real user will try and login 1000 times in 10 seconds with all different passwords.
If you are using proper complexity requirements (length, mix of casing, numbers, symbols, and perhaps forbid repeat a char consecutively) then I'd say it's not really worth it. If you're in a situation where that would be required then probably password authentication would not be good enough for your situation anyway.
SSL
If your website in any way or on any page requests sensitive personal information, including passwords, then you should enable and enforce SSL across the entire site. This will ensure that all passwords are transmitted in encrypted form from the browser to the server, and that nobody can sniff the passwords off the network or modify the pages in transit (and alter the form postback url's).
Password Meter
You should run your password meter entirely in the browser. You should accept any and all passwords (with a min length of, for example, 6 characters) that the user enters, but feel free to hint to the user, from within the browser, whether they have entered a weak or strong password.

Resources