Temporary Password Security - Storing as Plain Text - security

How much of a security issue would it be to store temporary / machine generated passwords as clear text in a database?
I understand that passwords should be encrypted using a 1-way hash function with salt. This is especially true for user supplied passwords as users typically re-use them over and over again. If the database was stolen, a thief might be able to gain access to user user accounts on 3rd party websites such as: utility bills, social networks, even potential for online banking.
How much of an issue would it be to store temporary/machine generated "welcome" or "reset" passwords as clear text in a database? The password would be emailed to users and must be changed upon login. The passwords that they supply would then be hashed.
The reason for me asking is that there are a some nice properties to storing a temporary password as clear text. For example, if a user does not get the "welcome" or "reset" email, an admin can quickly look-up their temporary password.
Because the temporary password would be machine generated, if the database was stolen, the thief would not be able to access any 3rd party websites that the users log into. The thief would however be able to login to the application that generated the temporary passwords.
Assigning these passwords a small "expiration" would limit exposure, but overall I am just looking to see how dangerous this approach would be.

You should not store even machine generated passwords in plain text.
Let's see what an attacker can do, if he somehow gains only read access to your database with SQL-injection (i made a small demo how easy SQL-injection can be, just click the next-arrow to get a malicious input).
The attacker with read access, could demand a password reset for any e-mail address he likes. Because he can see the new generated token in the database, he could call the reset page with this token and therefore can change the password of this user. Unnecessary to say, that he can now impersonate the original user.
Handle the token just like every other password, even if it can not be used on other sites. The data accessible by the user-account could contain other data (like birthday, real name), that can be used to hack other sites.

You absolutely must not store passwords in a database at all, let alone in plain text. You should store hashes of them. See this answer for why. Then you need to build all your password-reset facilities around that fact. See also this answer about password reset features.

Related

Is it really dangerous to save hashed password in cookies?

There are many discussions about security risk for saving hash password in cookies, as upon accessing to the user's computer, a hacker can log in with the saved password. If a hacker has access to the user's computer, he can catch the password, as browsers also save passwords locally (encrypted of course). What is the difference between password set in cookies with that saved by the browser?
For obvious reason, a temporary GUID should be send instead of password. In any case, I believe that limiting access to the logged IP can close doors for attackers to use locally saved GUID. Of course, it will limit the length of logged period, as IP is usually dynamic and regularly changes; but I think it is worth of its noticeable security. Any idea?
I suppose the reason why you would want to store a hashed password in a cookie is to create a "remember me" cookie. So you need a value for the cookie that is secret, so that not someone else could easily guess it. Anyone with access to this value would be able to log in as this user, so it is actually an "extra password".
There are two risks involved here:
Most important is the risk of exposing the password. This would not only put your site at risk, but potentially other sites as well. Most users re-use their password for everything, and the password would probably give an intruder access to both the users email account and netbank. Someone with access to the hashed value may use brute force or rainbow tables to discover the original password (rainbow tables are long lists of pre-calculated hashes). Rainbow tables are easily available for passwords up to more than 8 characters, and even longer. You may avoid this by salting the password so that it is i.e. more than 20 characters before you create the hash (remember to store the salt in the cookie as well). A properly salted password hash calculated with a safe hashing algorithm should be quite safe.
The other risk is connected to the fact that the user must change his original password to make the hashed password string invalid. It is impossible for the user to actually turn off this feature once it is turned on. You may delete the cookie when he un-checks the "remember me" button, but that will have no effect if the cookie already is compromised. What if his computer is i.e. stolen? If the user has checked this button on one computer then he must have access to that computer to disable this feature.
Yes, it's less secure to use the hashed password in a cookie. There is a difference between saving it in the browser and sending it over the wire: unless you're always using SSL, an attacker doesn't need access to the machine to read the cookie out of the request.
It's much safer to send a random value, as then there's no tie to the user's actual password: it's possible to expire a session by forgetting the random value, without having to get the user to change their password. Also if the attacker does get the hashed value out of the cookie, it may be possible for them to recover the actual password if that's what's sent.
as upon accessing to the user's computer, a hacker can log in with the
saved password. If a hacker has access to the user's computer, he can
catch the password, as browsers also save passwords locally (encrypted
of course).
Not sure what you mean here. If you ask IE to remember your password for a site and someone has the password to your computer and can use your IE then yes, he can log-in using your password. But this is not related to hashing or cookies etc.
First of all, a hashed password can not be retrieved. So if someone has the hash of your password, he does not know your password.
When you login to a site that requests a password, you provide the password which is send encrypted. The standard practice is to store the user's password as a hash i.e. not the password itself. So you type the password and the receiving server will compare the hash with the one stored.
Now related to your question on sending the hashed password inside a cookie, this is related to session management. I.e. to determine whether a user has already succesully loggedin or not.
IMHO using just the hashed-password as a way to determine if the user has already logged-in when using plain HTTP is not a good idea.
But if this what you ask, it is another topic.
I.e. how to best do session management over HTTP connections
Times when you should ask the user to re-enter their password:
When they try to change their password.
When they try to change their email address.
When they try to change their security information (anything that can be used to recover their password, including username, email address, security question, etc.).
When they try to access highly secure account information and have not entered their password for more than 15 minutes or so (if all information is highly secure, you should flat out log them out for inactivity instead). Amazon does this a lot.
Saving a hashed password makes this less effective.
As an aside, you should already be using cookies that are Secure (won't transmit over HTTP), HttpOnly (not accessible via javascript) to protect against XSS attacks. Of course, if someone hacks the person's machine completely they'll just install a keylogger.

Why aren't original passwords stored?

I am new to web development. Am I allowed to store users' original passwords? I know good practice is to store the hashed password using a salt, but why don't we store the original password?
Is it because the database is easily hacked, so hashing protects passwords? Are there any other reasons? If not, I would like to store the original password if it is legal to do so.
The legality depends on the country you live in. But there are best practices, too. And a best practice is to encrypt user's passwords. In this way, if someone breaks into your database, they will not be able to obtain the long list of passwords, and try each one of them in ebay, yahoo mail, and gmail. Users generally use the very same pair of username and passwords for many sites.
As Jon points in the comment, of course there is difference between hashing and encrypting. Hashing is a one-way, data-destructive process, which takes an arbitrary-length string as input, and outputs a fixed-length string. This string is defined in such a way, that changing any single bit in the original input, will cause the hash to be different. If you have a hash, therefore, it is not possible to reconstruct the original text (i.e. it is not possible to recover the password).
On the other hand, encryption proper is a technique where you can recover the original password, knowing secret keys, passwords, etc.
Usually, you want to hash passwords, not encrypt them: it's not necessary, and it is more complex to setup. You are not supposed to recover password either: you will just regenerate them.
Imagine if Facebook was hacked, it didnt encrypt any of the user's passwords. Facebook itself has around 200 millions(?) users
What if all of the 200 million passwords were leaked to some evil organization? Many users use same password as their mails or any other sensitive online services such as bank accounting.
Facebook wouldn't be safe at all once. Would you register an account there?
I don't know if it's legal, but nonetheless I would advise against it for at least three reasons:
This is not only about hackers getting access to your passwords. Users often have the same password for multiple accounts (also they shouldn't have). So who says we can trust you or other people who have legal access to this data?
It doesn't matter how secure you think your server is. There is no such thing as absolut security for a server. You should consider that it could be hacked eventually. And don't believe it'll never happen. Hope for the best, but always plan for the worst!
I would use every easy and cheap security I can get to secure not only my data, but also the data of the users. And the method of using a salt+hash is cheap. It will cost you 2 lines of Code. It
Yes, it's perfectly legal, though absolutely not recommended to store passwords in plaintext. And it's not that your actual live database can be compromised: even a backup copy can be stolen (without you ever knowing it).
When passwords are stolen, this is very bad for your actual users, since very few of them actually use different passwords for different sites.
It is legal according to the law. Some companies store the password in plain text, so that it is recoverable.
However, for safety reasons this is a bad idea. Once in a while, some company gets hacked and their database is accessed. In some cases, this exposes the passwords of thousands of users. This will severely damage the image of your company, and is even more a security risk when the password is not hashed.
If you want the password to be recoverable, at least encrypt it so that it is not easily viewable by accessing the database.
The original password isn't stored because once the database has been hacked your vulnerable information is at risk including your password so encrypting will not do anything once they have access through other sources. Depending on where you live some sites will store your password in plain text, For example, if your password is Appletree1234 they will stored your password in plain text as Appletree1234. According to Lifehacker.com, when you enter your credentials on the site, it checks them against the database to see if they match.

does it make sense to send password information during email communication from websites

Most of the online sites on registration do send a link to activate the site and on any further correspondence with the end user they provide information about the site and also provide the login credentials with password in clear text (as given below)
Username - myname#gmail.com
Password - mysecretpassword
What would you do in such a case? From a usability perspective does it make sense to send the password information in clear text or should you just avoid sending this information. I was under the impression that most of the passwords are MD5 hashed before storing in the database and hence the service provider will not have any access to clear text passwords, is this a security violation?
It's a commonly-held fallacy that if you receive a password in plain-text it means they aren't stored securely - passwords like any other data can be stored using reversible encryption.
Having said that, it's pretty likely anyone that sends you a plaintext password does not have a clue about security and is probably storing them carelessly (unless the passwords are used as weak real-world identifiers, say as part of an in-store membership scheme, in which case they shouldn't be called passwords lest your customers get confused).
If you send a password plain-text you may as well assume that if it is linked to something important then it has been compromised. There are just too many weak points. You can also do a lot more unintentional damage.
The email could be intercepted giving someone else the password.
Someone could see them open the email on their screen (been at mates houses and had this happen to both of us so many times, and every time is a massive headache to go change all your passwords).
The email might be forwarded to other addresses which are not secure.
The email might bounce/encounter a server error and then you (perhaps your untrusted staff or outsourced helpdesk too?), and the email server's system admin will probably get copies of the original email.
Someone who obtains access to the user's emails through a cookie hijack or even just a briefly unattended open email account will now be able to see their password. Worse, their password is probably used elsewhere (or at least has a common stem, e.g. "password1", "password1$$" "passwordSuperSecure123") so you've now compromised more than just your own service. Worse still, it might be the password to the email account that's been hijacked and now they can steal this person's email account and thus identity for a much longer time than the expiry date on the cookie/session. (This has all happened to people I know).
Yes, this is definitely a security violation. Only a salted and hashed version of passwords should be stored.
It is common to have reset password functionality that sends either a temporary auto-generated password (which should be good for only one login) or a one-time reset link. This does mean your other accounts are only as secure as your email.
However, you should steer clear of any site that will email your actual password in clear text.
There are always trade-offs, and developers have to consider useability, the savvy-ness of the intended users, the secrecy and importance of the data, the frequency that the website will be used, and so on. Of course users don't want their privacy violated, but on the other hand "ordinary" web users may be turned off by having to remember a password, or even having to invent one in the first place (some websites simplify user registration by generating a random password and emailing it). Website developers have a responsibility to keep the users' best interests in mind when designing security.
My advice is that passwords should only be emailed in the clear when they are randomly generated. This avoids the following awkward scenario: a user registers with a password which they are already using for various other web services, and then receives a registration confirmation email containing the password they just entered. A lot of users may not be security-conscious enough to use unique passwords for every website, but they are security-conscious enough to recognize that "sensitive" passwords should not be sent around by email.

Is it advisable to store a hashed password in a cookie?

I want user's to be able to select a "remember me" box on my website so they need not log in each time they come. So, I need to store a unique ID in a cookie to identify them. Is it safe to hash their password with sha512 and a long salt in PHP and store that value in the cookie?
If the cookie was stolen, would their password be at risk?
Obviously it must be connected to their password somehow, otherwise if the cookie value was guessed or stolen, the user would not be able to stop someone else logging in.
Also, is it advisable to use a GUID at all as the unique identifier?
Thanks,
Ben
Remember, the hash of the password is effectively the same as their password. Somebody who stole the hash would have the same access to the user's account as if they had stolen their password. Therefore it is not advisable to store a hash of the user's password in a cookie unless there was some other information not stored with the cookie that is used to authenticate (i.e. 2-factor authentication).
Here is an excellent article on this very topic. Many of the answers to your question are hitting on techniques outlined in it.
There's a low risk with a good algorithm and large salt, but why take any unnecessary risk?
If you just need to identify the user, then store something that can uniquely identify the user, like a guid along with some other stored verification code (not their password, some random long string). I wouldn't use a guid alone as it would not be a safe method of authentication.
It wouldn't hurt to have some kind of "password" in the cookie along with a user id (to prevent users from changing the uid to that of another user), just don't make the "password" the same as the actual user's password.
And just because it's a hash doesn't necessarily mean it's one-way (well, by definition it does, but there are utilities to generate MD5 plaintexts and I would guess it's only a matter of time before it happens to others). I would hash some kind of secondary password.
An alternative way of doing this might be use the cookie as an encrypted storage for only indirection data. You'd need some sort of unencrypted identifier that would serve as a pointer to the key (or the required information to derive the key) in the application's database, followed by a blob encrypted by the key obtained from the identifier, which itself would contain some sort of one-time-usable identifier that authenticates the session.
Given the following assumptions:
Your database is secure (e.g., your application can access it, but your user cannot directly do so, and also assuming that the application has been proofed against SQL injection)
Your salts are strong; that is, reasonably high-entropy enough that attempting to crack the salted password is infeasible even if the password is known
Then what this would provide is a method by which one can be reasonably certain that the session is not able to be hijacked or stolen in any way. That is to say that a copied cookie is only of limited usefulness, since the user must not have used the cookie between its theft and usage by an attacker.
While this protects against replay, it also means that if someone does manage to steal the cookie at exactly the right time, and manages also to use it before the original, legitimate user does, the attacker now is in control of the session. One can limit a session to an IP address to mitigate that risk (somewhat; if both the user and the attacker are behind the same NAT, which is the most likely scenario in any home or small-to-medium business network) then this point is pretty moot, since the IP address would appear to be the same anyway. Also useful might be limiting to the current user agent (though that can break unexpectedly if the user updates their browser and the session does not expire at browser close time), or finding some method by which one can identify the computer that the user is on just well enough that there is reasonable certainty that the user hasn't moved the cookie from one system to the next. Short of using some binary plugin (Flash, or Silver/Moonlight), I'm not sure that the latter is possible.
To protect against a permanent session hijacking, require that the user to reauthenticate him- or herself periodically (e.g., limit the allowed session lifetime or require something like a token/fob/dongle) and require that the user reauthenticates him- or herself upon entering sensitive areas of the application, such as password change and potentially dangerous actions, patterns or behaviors such as the deletion of data, unusual usage patterns, bulk actions, and so forth.
It is difficult to secure applications and yet retain their ease-of-use. If done carefully, security can be implemented in a manner which is minimally intrusive and yet still effective—well, for most Internet-facing applications, anyway.
It's not advisable, but if your gonna do it, at least salt your passwords before you do so. This will stop people from using hash crackers if they do manage to get hold of your visitor's cookies.

How does hashing and salting passwords make the application secure?

As much as I understand it is a good idea to keep passwords secret from the site administrator himself because he could try to take a user's email and log into his mailbox using the same password (since many users use the same password everywhere).
Beyond that I do not see the point. I know it makes more difficult the dictionary attack but... if someone unauthorized got into the database, isn't it too late to worry about passwords? The guy has now access to all tables in the database and in a position to take all the data and do whatever he wants.
Or am I missing something?
The bigger problem is that people tend to use the same password everywhere. So if you obtain a database of usernames and unsalted passwords, chances are good they might work elsewhere, like hotmail, gmail etc.
The guy might be in a position to do everything he/she wants to your system, but you shouldn't allow him/her to do anything with other systems (by using your users' passwords).
Password is a property of your users. You should keep it safely.
Many of your users use the same credentials (usernames/passwords) at your site as they do at their bank. If someone can get the credentials table, they can get instant access to a bunch of bank accounts. Fail.
If you don't actually store passwords, then attackers can't steal your users' bank accounts just by grabbing the credentials table.
It relies on the fact that a hash is a one way function. In other words, its very easy to convert a password into a hash, but very difficult to do the opposite.
So when a user registers you convert their chosen password into a hash and store it. At a later point they login using their password and you convert the password to its hash and compares it this is because, to a high level of probablity if (passwordhashA == passwordhashB) then passwordA=passwordB.
Salting is a solution to a related problem. If you know that someones passwordhash is, say ABCDEF, then you can try calcuolating hashes for all possible passwords. Sooner or later you may find that hash('dog') = ABCDEF, so you know their password. This takes a very long time, but the process can be speeded up by using pre-created 'dictionaries' where, for a given hash you can look up the corresponding password. Salting, however means that the text that is hashed isnt a simple english word, or a simple combinationofwords. For example, the case I gave above, the text that would be hashed is not 'dog', but is 'somecrazymadeuptextdog'. This means that any readily available dictionary is useless, since the likelyhood of it containing the hash for that text is a lot less than the likelihood of it containing the hash for 'dog' This likelihood becomes even lower if the salt is a random alphanumeric string.
The site admin may not be the only person who gets access to your password. There is always the possibility of a dump of the whole database ending up on a public share by accident. In that case, everybody in the world who has internet access could download it and read the password which was so conveniently stored in cleartext.
Yes, this has happened. With credit card data, too.
Yes, it is highly probable that it will happen again.
"if someone unauthorized got into the database, isn't it too late to worry about passwords?"
You're assuming a poor database design in which the authorization data is comingled with application data.
The "Separation of Concerns" principle and the "Least Access" principle suggest that user credentials should be kept separate from everything else.
For example, keep your user credentials in an LDAP server.
Also, your question assumes that database credentials are the only credentials. Again, the least access principle suggests that you have application credentials which are separate from database credentials.
Your web application username and password is NOT the database username and password. Similarly for a desktop application. The application authentication may not necessarily be the database authentication.
Further, good security suggests that access to usernames and passwords be kept separate from application data. In a large organization with lots of database users, one admin should be "security officer" and handle authentication and authorization. No other users can modify authorization and the security officer is not authorized to access application data.
It's a quick audit to be sure that the security officer never accesses data. It's a little more complex, but another audit can be sure that the folks with data authorization are real people, not aliases for the security officer.
Hashed passwords is one part of a working security policy.
Of course, storing hashes of passwords instead of plain-text does not make your application secure. But it is one measure that increases the security. As you mentioned if your server is comprised this measure won't save you, but it limits the damage.
A chain is only as strong as its weakest link
Hashing passwords is only strengthening one link of the chain. So you will have to do more than that.
In addition to what has already been said regarding salting, there's another problem salting solves :
If you use the same salt everywhere (or no salt at all), it's possible to say just by looking at the database that user foo and user bar both have the same password (even if you don't know what the password is).
Then, if one achieve to get foo's password (using social engineering for example), bar's password is known as well.
Also, if the salt is everywhere the same, one can build up a dictionary dedicated to this specific salt, and then run a brute-force attack using this 'salted' dictionary.
This may be a bit off topic, but once in a while, I notice some websites are not using hashing (for example, when I click the forgot password button, they send me my password in cleartext instead of allowing me to chose another one).
I usually just unsubscribe, because I don't think I can trust a website designed by people not taking the elementary precaution of hashing passwords.
That's one more reason for salting:)
People seem far too complacent about this! The threat isn't some guy with shell access to your system or to the backup media, it could be any script kiddie who can see the unprotected (but dynamic) part of your site(*) and a single overlooked SQL injection threat. One query and suddenly he can log in as any user, or even as an admin. Hashing the passwords make it far less likely that the attacker can log in as any particular user using their password -or- update a record with their own password.
(*) "unprotected" includes any part of the site that can be accessed as a self-registered user. Contrast this to a bank site, for instance, where you must have an existing bank account to gain access to much of the site. An attacker could still open a bank account to gain access to the site, but it would be far easier to send big guys with bigger guns after him when he tries to crack the system.

Resources