Security of a password-only login? - security

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.

Related

Is just a long password more secure than a user/password combination?

Basically, my question is already in the title.
The idea is:
Option 1:
Password: XXXXXXXX (8-character)
Option 2:
Username: XXXX (4-character)
Password: XXXX (4-character)
Should be equally secure, right?
From a purely theoretical point of view, I would say yes. At first. The number of combinations should equal, if I am not mistaken.
But there are other things to consider.
Firstly, as Alex Shesterov mentioned, you would not have the possibility to change a password for a given user.
Secondly, if two persons use the same password, which is maybe hash-generated, you cannot distinguish these users.
Therefore it is hard to decide if someone is trying to get access by guessing (brute-force) or if multiple users are using the same password. If you have a user/password combination you can count the number of accesses for each user seperately.
Another point is implementation. If you only have the password for identification, you would have to crawl all of you password database for each access, which takes linear time ( O(n) ), which means that a growing user-base would increase the time and effort, which is necessary for each single access.
Lastly, for an attacker it would be only necessary to find just one valid password, instead of a valid user/password combination. Since you cannot distinguish different users, if they may use the same password, this possibly means that an attecker can gain access to the complete system, as all users are equal. Therefore you would need additional means to safely distinguish users wihtin your system.
In the end, I would stick to the user/password combination and change the needed complexity for the password and its length.
edit: removed the link to the birthday problem, since it is not applicable, as discussed in the comments.

Should the password field be unique?

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.

Increasing security of web-based login

Right now my login system is the following:
Password must be at least 8 characters long, and contain at least one upper and lowercase letter, a number and a symbol.
Password can't contain the username as its substring.
Username, salted+hashed (using SHA2) password stored on db.
The nonce (salt) is unique for each user and stored as plaintext along with the username and password.
The whole login process can only be made over TLS
How would you rank the effectiveness of the following measures to increase security?
Increase password length
Force the user to change the password every X period of time, and the new password can't be any of the last Y previous passwords
Increase nonce size from 32 bytes to 64 bytes (removed for uselessness)
Encrypt the salt using AES, with the key available only to the application doing authentication
Rehash the password multiple times
Use a salt that's a combination of a longer, application-wide salt + unique user salt on the db.
I am not very fond of 1 and 2 because it can inconvenience the user though.
4 and 6 of course are only effective when an attacker has compromised the db (eg: via SQL injection) but not the filesystem where the application is in.
The answers may depend somewhat on the nature of the website, its users and attackers. For instance, is it the kind of site where crackers might target specific accounts (perhaps "admin" accounts) or is it one where they'd just want to get as many accounts as possible? How technical are the users and how motivated are they to keep their own account secure? Without knowing the answers, I'll assume they're not technical and not motivated.
Measures that might make a difference
5) Rehash the password multiple times. This can slow down all brute force attacks significantly - hash 1000 times and brute force attacks become 1000 times slower.
4) Encrypt the salt using AES, with the key available only to the application doing authentication How would you make it available only to the application? It has to be stored somewhere and, chances are, if the app is compromised the attacker can get it. There might be some attacks directly against the DB where this makes a difference, so I wouldn't call this useless, but it's probably not worthwhile. If you do make the effort, you might as well encrypt the password itself and any other sensitive data in the DB.
6) Use a salt that's a combination of a longer, application-wide salt + unique user salt on the db. If you're only concerned about the password then yes, this would be a better way of achieving the same result as 4) and, of course, it's very easy to implement.
Ineffective measures
3) Increase nonce size from 32 bytes to 64 bytes. Computing rainbow tables is already completely impractical with any salt, so this would only make a difference if the salt was not known to the attacker. However, if they can get the hashed password they could also get the salt.
Ineffective and annoying measures
1) Increase password length Increasing password length beyond 8 won't make a practical difference to the brute force time.
2) Force the user to change the password I agree, this will always be worked around. In fact, it may make the site less secure, because people will write down the password somewhere!
Increasing password length add a few bits of entropy to the password.
Requiring frequent password changes will generally force the users to use less secure passwords. They will need to figure out what the password is in May, June, July. Some#05x, Some#06x, Some#07x.
Can't say for sure, but I would expect the password length to be more significant in your case.
Slightly more secure. But if someone gains access to your data, they can likely gain access to the key.
Other than increasing CPU costs, you won't gain anything.
There are a number of well tried one-way password encryption algorithms which are quite secure. I would use one of them rather than inventing my own. Your original items 1, 2, and 5 are all good. I would drop 3, and 4.
You could allow pass phrases to ease password length issues.
I would suggest that you read http://research.microsoft.com/en-us/um/people/cormac/papers/2009/SoLongAndNoThanks.pdf
This paper discusses part of the reason it is hard to get users to follwo good security advice; in short the costs lie with the users and they experience little or no benefit.
Increasing the password length and forcing more complex passwords can reduce seciryt by leading to one or both of; reused passwords between sites/applications and writing down of passwords.
3 Increase nonce size from 32 bytes to 64 bytes
4 Encrypt the salt using AES, with the key available only to the application doing authentication
5 Rehash the password multiple times
These steps only affect situations where the password file (DB columns) are stolen and visible to the attacker. The nonce only defeats pre-hashing (rainbow tables), but that's still a good thing and should be kept.
(Again, under the assumption you're trying to minimize the impact of a compromised DB.) Encrypting the nonce means the attacker has an extra brute-force step, but you didn't say where the encryption key for the nonce is stored. It's probably safe to assume that if the DB is compromised the nonce will be plaintext or trivially decrypted. So, the attacker's effort is once again a brute-force against each hash.
Rehashing just makes a brute-force attack take longer, but possibly not much more so depending on your assumptions about the potential attacker's cracks/second.
Regardless of your password composition requirements a user can still make a "more guessable" password like "P#ssw0rd" that adheres to the rule. So, brute force is likely to succeed for some population of users in any case. (By which I mean to highlight taking steps to prevent disclosure of the passwords.)
The password storage scheme sounds pretty good in terms of defense against disclosure. I would make sure other parts of the auth process are also secure (rate limiting login attempts, password expiration, SQL injection countermeasures, hard-to-predict session tokens, etc.) rather than over-engineering this part.
For existing:
e1: I see where you're coming from, but these rules are pretty harsh - it certainly increases security, but at the expense of user experience. As vulkanino mentions this is going to deter some users (depends on your audience - if this is an intranet application they have no choice... but they'll have a yellow sticky with their password on their monitor - cleaners and office loiterers are going to be your biggest issue).
e2: Is a start, but you should probably check against a list of bad passwords (eg: 'password', 'qwerty', the site URL)... there are several lists on the net to help you with this. Given your e1 conditions such a scan might be moot - but then surely users aren't going to have a username with 8 chars, upper+lower, a symbol and a number?
e3: Good call - prevent rainbow attacks.
e4: Unique salt prevents identification of multiple users with the same password, but there are other ways to make it unique - by using the username as a secondary salt+hash for example.
e5: Solid, although TLS has built in fall-backs, the lower end TLS protocols aren't very secure so you may want to check you're not allowing these connections.
New ideas:
n1+n2: e1 is already painful enough.
n3: No discernible benefit
n4: No discernible benefit - whatever the encryption process is would be available in the code, and so also likely compromised. That is unless your DB and App servers are two different machines hardened for their own tasks - in this case anything you can avoid storing with the password is helpful in the event the DB is compromised (in this case dropping unique salt from the database will help).
n5: Rehashing decreases brute force attack speed through your application - a worth while idea in many ways (within reason - a user won't notice a quarter second login delay, but will notice a 5 second delay... note this is also a moving target as hardware gets better/faster/stronger/work it)
Further points:
Your security is only as good as the systems it is stored on and processed through. Any system that could be compromised, or already has a back door (think: number of users who can access the system - server admins, DBAs, coders, etc) is a weak link.
Attack detection scripts in your application could be beneificial - but you should be aware of Denial of Service (DoS) attacks. Tracking failed logins and source is a good start - but be aware if you lock the account at 5 failures, someone could DoS a known account (including the admin account). Being unable to use the App may be as bad as loosing control of your account. Multi-hash (n5) slows down this process, picking a slower hash algorithm is a good step too, and perhaps building in re-attempt delays will help too (1 second on first fail, 2 on second, etc)- but again; be DoS aware. Two basic things you might want to filter: (1) multi attacks from the same source/IP (slow down, eventually prevent access from that IP - but only temporarily since it could be a legitimate user) perhaps further testing for multiple sets of multi attacks. (2) Multi attacks from different IPs - the first approach only locks a single user/source, but if someone uses a bot-net, or an anonymizing service you'll need to look for another type of suspicious activity.
Is it possible to piggy-back off another system? You could use an LDAP, or Active Directory server in your domain or use OpenID or OAuth or something similar. Save yourself all these headaches by off loading the work ;) {Inter-system security still needs to be addressed if you're a middle man} Plus the less passwords users have to remember (and rules attached to each) the more likely they are to have a good password, that isn't written down, etc.
I don't consider any of those things to increase your password security. The security of the password stored in the database is only relevant if you expect someone to obtain a copy of the database. Using a (perceived) stronger hash function in the database only obfuscates your application. In fact a salted MD5 would be fine (I am aware of the attacks on MD5, and don't believe any of them to be relevant to password hashing).
You might be better relaxing the password rules to get better security, as if you require at least one upper and lower LATIN letters, you effectively force non-latin keyboard users to use alien letters (try typing upper and lower case latin letters on a cyrilic keyboard). This makes them more likely to write it down.
The best security would be to avoid using passwords in their entirety. If it is an enterprise application in a corporate that uses Active Directory, consider delegating authentication instead of writing your own. Other approaches can include using an Information Card by making your application claims-aware.
How about encrypting the password in client browser already with MD5/SHA, then treat the hash as user's password at server side. This way the password isn't in plain text when it travels over SSL/TLS nor it is never-ever in plain text in server either. Thus even it is stolen by hackers at any point (man-in-the-middle, server/db hacks), it cannot be used to gain access to other web services where the user might have same email/username+password combo (yes, its very common...)
It doesn't help with YOUR site login security directly, but it certainly would stop hacked password lists spreading around the net if some server has been hacked. It might work to your advantage as well, if another, hacked site applies the same approach, your site user's aren't compromised.
It also guarantees all users will have decent alphanumeric password with enough length and complexity, you can perhaps then relax your requirements for password strength a little :-)

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.

Ultimate Hash Protection - Discussion of Concepts

Ok, so the whole problem with hashes is that users don't enter passwords over 15 characters long. Most only use 4-8 characters making them easy for attackers to crack with a rainbow table.
Solution, use a user salt to make hash input more complex and over 50chars so that they will never be able to generate a table (way to big for strings that size). plus, they will have to create a new table for each user. Problem: if they download the db they will get the user salt so you are back to square one if they care enough.
Solution, use a site "pepper" plus the user salt, then even if they get the DB they will still have to know the config file. Problem: if they can get into your DB chances are they might also get into your filesystem and discover your site pepper.
So, with all of this known - lets assume that an attacker makes it into your site and gets everything, EVERYTHING. So what do you do now?
At this point in the discussion, most people reply with "who cares at this point?". But that is just a cheap way of saying "I don't know what to do next so it can't be that important". Sadly, everywhere else I have asked this question that has been the reply. Which shows that most programmers miss a very important point.
Lets image that your site is like the other 95% of sites out there and the user data - or even full sever access - isn't worth squat. The attacker happens to be after one of your users "Bob" because he knows that "Bob" uses the same password on your site as he does on the banks site. He also happens to know Bob has his life savings in there. Now, if the attacker can just crack our sites hashes the rest will be a piece of cake.
So here is my question - How do you extend the length of the password without any traceable path? Or how do you make the hashing process to complex to duplicate in a timely manner? The only thing that I have come up with is that you can re-hash a hash several thousand times and increase the time it would take to create the final rainbowtable by a factor of 1,000. This is because the attacker must follow that same path when creating his tables.
Any other ideas?
Solution, use a user salt to make hash
input more complex and over 50chars so
that they will never be able to
generate a table (way to big for
strings that size). plus, they will
have to create a new table for each
user. Problem: if they download the db
they will get the user salt so you are
back to square one if they care
enough.
This reasoning is fallacious.
A rainbow table (which is a specific implementation of the general dictionary attack) trades space for time. However, generating a dictionary (rainbow or otherwise) takes a lot of time. It is only worthwhile when it can be used against multiple hashes. Salt prevents this. The salt does not need to be secret, it just needs to be unpredictable for a given password. This makes the chance of an attacker having a dictionary generated for that particular salt negligibly small.
"The only thing that I have come up with is that you can re-hash a hash several thousand times and increase the time it would take to create the final rainbowtable by a factor of 1,000."
Isn't that exactly what the Blowfish-based BCrypt hash is about? Increasing the time it takes to compute a hash so that brute force cracking (and rainbow table creation) becomes undoable?
"We present two algorithms with adaptable cost (...)"
More about adaptable cost hashing algorithms: http://www.usenix.org/events/usenix99/provos.html
How about taking the "pepper" idea and implementing it on a separate server dedicated to hashing passwords - and locked down except for this one simple and secure-as-possible service - possibly even with rate-limits to prevent abuse. Gives the attacker one more hurdle to overcome, either gaining access to this server or reverse engineering the pepper, custom RNG and cleartext extension algorithm.
Of course if they have access to EVERYTHING they could just evesdrop on user activity for a little while..
uhmm... Okay, my take on this:
You can't get the original password back from a hash. I I have your hash, I may find a password that fits that hash, but I can not log in to any other site that uses this password, assuming they all use salting. No no real issue here.
If someone gets your DB or even your site to get your config, you're screwed anyway.
For Admin or other Super Accounts, implement a second mean of verification, i.e. limit logins to certain IP ranges, use Client-Side-SSL Certificates etc.
For normal users, you won't have much chance. Everything you do with their password needs to be stored in some config or database, so if have your site, I have your magic snake oil as well.
Strong Password limitations don't always work. Some sites require passwords to have a numeric character - and as a result, most users add 1 to their usual password.
So I'm not entirely sure what you want to achieve here? Adding a Salt to the front of the users password and protecting Admin accounts with a second mean of authentication seems to be the best way, given the fact that users simply don't pick proper passwords and can't be forced to either.
I was hoping that someone might have a solution but sadly I am no better off then when I first posted the question. It seems that there is nothing that can be done but to find a time-costly algorithm or re-hash 1,000's of times to slow down the whole process of generating rainbow tables (or brute-forcing) a hash.

Resources