43

I look after a system which holds a lot of "low grade" information, nothing financial but name/address/email etc. Someone has suggested that we up the security from the current in house password encryption algorithm to use ICO recommended hash/salting. I've done a bit of reading around and am struggling to see the benefit, my argument has gone back to the "experts" who are suggesting this but they wont (can't) answer my fairly simple question.

As far as I can tell, hashing/salting prevents the password being read and decrypted by a hacker, and it's excellent for this, no argument. But unless I'm missing something, in order to read the password value the hacker has to have access to the database so they can steal the password values?... if they have access to the database then they don't actually need the password(s) as they can just steal the data direct from the database i.e. the application access they gain from the passwords would give them nothing more than reading the database direct?...

What am I missing?

Deer Hunter
  • 5,297
  • 5
  • 33
  • 50
Steve
  • 487
  • 1
  • 5
  • 8
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackexchange.com/rooms/30971/discussion-on-question-by-steve-is-there-any-real-value-in-hashing-salting-passw). – Rory Alsop Nov 01 '15 at 15:05
  • Question's protected, so commenting... Remember that database access is different to having credentials. DB read means you can grab & use data as long as you have access (like with cash). DB write means you can manipulate, but also only until this is fixed. Then after the fact, unless you lock & force all users to renew credentials with identity verification, intruders could still use old credentials & go undetected maybe & have others take blame (like a credit card). – Arc Nov 01 '15 at 16:29
  • This has to be a duplicate of another question on here. – AKHolland Nov 02 '15 at 16:44

12 Answers12

106

Users often use the same passwords on multiple sites. Your site might not have any financial data, but what if the same password is used for their bank, or for an online store?

You could argue that this isn't your problem, but it is a common issue, and is why whenever a breach happens, one of the immediate statements is "change your password, and change it on any other sites where you've used the same password".

If your site used something like Bcrypt (without flaws in the implementation - see Ashley Madison), the chances of an attacker being able to work out what passwords have been used is slimmer, and it increases the time for users to be able to change their passwords elsewhere. If you just store the password in your DB without any hashing, an attacker can wander off with the email addresses and passwords and start attacking another site immediately.

Email address and password pairs are often traded between attackers too, in the form of "combo lists", which means that even if the original attacker is only interested in your site, they might be able to get some benefit by selling the data to someone else.

Added in response to comment on question mentioning 2-way encrypted storage

The problem with a 2 way encryption approach is that the information to decrypt must be stored somewhere in the system. If an attacker gains access to your database, there is a good chance they have access to your encryption key too. A hash can't be reversed in this way - online tools for reversing hashes effectively look up the hash in a pre-computed list.

Even if they don't have the encryption key, they might be able to work out what the key was - they can use a known plaintext attack by entering a password to your system and seeing what the result is. It probably wouldn't be a quick process, but it could be worth doing if there were any high value targets in your data (celebrities, politicians...).

On the other hand, with a strong, salted, hash, the only way to find the original password with strong certainty is to hash every possible input, using the appropriate salt. With something like Bcrypt, this would take years, although weak passwords will still be found relatively quickly.

Matthew
  • 27,233
  • 7
  • 87
  • 101
  • OK that's a fair point, the site is written in classic ASP so I'd have to find a component to do this, which shouldn't be too hard, but then I have to somehow force a password change for all users... I can't change it as I can't then send them there password (or can this be done in code?) i.e. generate a password and email it?, then force a password change on login... what else! – Steve Oct 28 '15 at 12:41
  • That will be possible and seems like the best solution. The only other thing I can think is that the password reminder will have to be removed and a password reset used instead... any other gotchas I need to think about? – Steve Oct 28 '15 at 15:58
  • 1
    @Steve Lots of things that are worth considering, but most of them are covered in the OWASP Authentication Cheatsheet https://www.owasp.org/index.php/Authentication_Cheat_Sheet - well worth reading – Matthew Oct 28 '15 at 16:00
  • 1
    In addition - your employees likely have access to the decryption key ... and so what's to stop them from decrypting the entire password database and posting it online after leaving the company? As mentioned people re-use their passwords so there's likely to be some damage done – Chris Oct 28 '15 at 18:08
  • 5
    @Steve, you don't need to force a password change on your users, that's a policy decision. As I can't tell from your question all details, I see two options. 1, if pwds are truly encrypted, just decrypt and hash/salt with new cryptographically secure algorithm. 2, if pwds are one-way hashed with current (weaker) algorithm, write new code that fires at login and creates a the new hash/salt with the user supplied password (assuming the old verifier indicates a match). No one need be bothered. Down the road to get 100% compliance notify any remaining users that they have to do a password reset. – Andrew Philips Nov 01 '15 at 15:59
  • @AndrewPhilips that would introduce the problem of how to dispose of the old "decryptable" database, and any copies left behind would render the whole change useless. Password reset is the way to go here. – GnP Nov 03 '15 at 21:07
  • @gnp, there's no problem of disposal, just delete/null the containing the old password data when recording the new one. Steve's first comment was that he'd have to force a pwd change. He should know that it's technically feasible to not force a change. So, in this case, they have two questions: (1) a policy question (force pwd change?) and (2) a technical question (must all users change pwds?). Although, like you, I lean towards the change policy, there are times this can adversely affect a user community. In those cases, it's nice to have a choice. – Andrew Philips Nov 04 '15 at 02:07
49

Good question, and I'm glad you asked it. I want people to find this thread when they Google it so they -- hopefully -- won't make the same mistakes that many other companies make.

You shouldn't just hash passwords, you should salt them and make sure your hashing algorithm uses some form of SlowEquals. You shouldn't stop there: you should use a secure hashing algorithm that greatly resists collisions, such as bcrypt or scrypt.


Why salt? What are collisions?

I'm going to use md5 as an example because it's very well-known. Do not use it, as it's vulnerable to collisions, and is very fast, which means it's much easier to break. Let's imagine you just hash your passwords without a salt. You would end up producing a static output pretty much every single time.

For example, "myDarnPassword" would end up being converted to "aca6716b8b6e7f0afa47e283053e08d9" when hashed as md5. At this point, you could create a dictionary attack and use rainbow tables. You could even generate a database that converts as many random characters into an easily-searchable database that won't require time-consuming rainbow table lookups. You can slowly create that over time and look up hashes later.

You'd create a table looks like this:

+-------------------+----------------------------------+
| PASSWORD          |           UNSALTED_HASH          |
+-------------------+----------------------------------+
| myDarnPassword    | aca6716b8b6e7f0afa47e283053e08d9 |
+-------------------+----------------------------------+
| pleaseDontSueMe11 | 0dd395d0ec612905bed27020fb29f8d3 |
+-------------------+----------------------------------+

Then you would select from the database somewhat like this:

SELECT [password] FROM [table] WHERE [unsalted_hash] = 'aca6716b8b6e7f0afa47e283053e08d9'

And it would return myDarnPassword, plus any collisions which occurred.

With enough processing power and time, you could create trillions of combinations, and quite easily crack a large number of passwords in a very short time (I might recommend breaking databases up into password lengths because of the sheer number). You'd need a colossal amount of hard drive space for this, though.

At that point, all you really have to do is look it up without wasting processing power on brute-forcing everything every time. And if you've stolen other people's passwords in the past from a database, you can add those, and convert them to hashes. Many websites have already done this.

When a website validates your password, they will compare the password to the stored hash, and if it matches the hash in the database, it's considered a valid password. You may then allow the user to log in.

Salting the hash can help defeat this attack, but it won't save you vs. collisions. You can compare the hacked hashes to your hash list that generated collisions, and then enter that password on a website, even if you have the wrong password: as long as the hash validates, you're pwned.


Who cares if someone cracks my passwords? I don't care!

Below is just a small collection of examples of what phishers and other malicious individuals could with your unhashed and unsalted plaintext passwords. It may not necessarily be used to target you directly, but let's say Hacker wants to target Person A. Let's deduce how you can target Person A.

  1. You are Hacker. Your job is to hack websites and develop a database to aggregate this information.
  2. Person A is a person of interest. Person A shows up in one of your hacked sites database. You now know their email address, and the password they're using for that website.
  3. Now you can try to log in to their email address with password you've stolen from that website. Sweet, it works!
  4. Now that you have access to their email, you download all of their emails through IMAP, or through their web-mail. At this point, you find lots of interesting things. They're communicating with Person B.
  5. You can actually google some people's usernames and email addresses, and it could show websites they post on. This will bring up other websites that the user uses. Maybe you can try to hack those websites, or maybe you can just deduce what they're into. Now you can pretend to be like them, or find additional information. Information/activities could include:
    • Usernames. Person A posts online as Mark Buffalo. That's a relatively unique name. You can then google Mark Buffalo, and look for websites that he posts on. Maybe he reveals more of his personality on other sites?
    • Passwords. Maybe Mark Buffalo has the same password on that website. Maybe you can log in to that website and view his private communications with others?
    • Personal Information. Because you know the identity of Mark Buffalo, what if he shares personal information on certains website? What if he posts on craigslist searching for male or female escorts, and he's left his phone number there? You already found his phone information, so you can find a way to set him up and blackmail him for money/information/power. This doesn't have much to do with salting the passwords unless you don't include the phone number, but they find their phone number on another website thanks to your leak. It's one of the many very powerful ways that information can be collected and used against you. This is, after all, an Information Security forum, so I want to use this example.
    • Family Information. Now it's getting creepy. We've got Mark Buffalo's personal information. Let's look into his social networking. Oh, he has a Facebook account (I don't). Can we access this with the same password? If Buffalo is using the same password/email combination, then probably. And you can probably deduce this from his email that you accessed earlier, where you found a lot of interesting things. We can now log in and read his Facebook messages. Now we know who his family members are. We can then coordinate the blackmail attack more easily.
    • Other Login Information. Since we got access to his email earlier, we see he also has a Skype account. One of them is secret. We log in, and see he's flirting with people on Skype. We now have more blackmail material.
    • Impersonation. You can now log in and impersonate Buffalo on a variety of websites. Maybe he's actually a straight-shooter and never went after any escorts, or anything of the sort? Well, now you can turn him into an escort-seeking reprobate, at least in appearance, by using his credentials to impersonate him online. Imagine the damage that could cause to a politician who was wrongly accused and forced to resign.
    • Things that make it easier to hack other people. You can then send emails to Person B with infected attachments, and pretend you know him. You've read enough emails, so you're able to imitate Mark Buffalo to the point where you seem just like him. You craft the email in a way that leaves Person B unsuspecting of what's really going on, and now you can do the same thing to Person B, or worse.

And that's just a small collection of ideas. There are a lot of different uses for someone else's credentials. Salt and hash your passwords, use collision-resistant hash algorithms such as bcrypt and scrypt, and prevent SQL injection attacks. Please don't turn me into an escort-seeking reprobate! Save Mark Buffalo!

(I'm aware some websites can block your attempt to access their services when using a different IP, but there are many ways around this, and not all websites do this).

By the way, congratulations on your potential class action lawsuit if you get hacked.

Mark Buffalo
  • 22,498
  • 8
  • 74
  • 91
  • Thanks for the story, I get the point. Although how they then issue a class action lawsuit against me is a little tenuous, if the user is using the same password everywhere then it could be against anyone – Steve Oct 28 '15 at 13:44
  • 7
    @Steve Well, they'd be able to show that you weren't doing all that was possible to protect password data provided to you - breach data is usually linked to a source. If multiple breaches occurred, but your system was the only one with plain text passwords, it won't look good. The rules vary based on country, but generally require showing that you have taken industry standard precautions, even if they seem overkill for a specific application. – Matthew Oct 28 '15 at 13:49
  • There are data trails. Little breadcrumbs that you can leave everywhere. If the `Hacker` is ever caught, chances are, they can pinpoint the origin of his malicious behavior and it would lead back to you, regardless of whether or not the other systems have unhashed and unsalted passwords. – Mark Buffalo Oct 28 '15 at 13:58
  • @Downvoter, do you have a word to share with us? Are you upset that I revealed common patterns used by malicious individuals that you're currently using yourself? Am I wrong? Did I offend you with my warped sense of humor? Please share. :) – Mark Buffalo Oct 28 '15 at 14:01
  • 5
    He can just reset all your passwords if he get access to your email. Just go to PayPal and bank sites blindy asking for a password reset. That's why you must be really proactive with email accounts , they are critical , you should use a very good password on your email + 2 way authentication – Freedo Oct 28 '15 at 15:33
  • @Freedo, agreed. – Mark Buffalo Oct 28 '15 at 15:37
  • 3
    Just gonna put this here too: https://xkcd.com/792/ – ford prefect Oct 28 '15 at 16:00
  • 7
    +1 esp. for last sentence. Many countries have privacy laws that apply to any service that offers user accounts. Even if you don't think your db has any sensitive info, the mere act of using industry-standard hash/salt practices may reduce your potential liability if you do get hacked - it shows that you are taking reasonable steps to not be the weakest link in a multi-part hacking operation. – Dan Henderson Oct 28 '15 at 17:10
  • 2
    @Steve `Although how they then issue a class action lawsuit against me is a little tenuous` -- It's called "negligence". In a legal setting, it means "failure to use reasonable care, resulting in damage or injury to another." This is grounds for a lawsuit. Just ask Sony, Ashley Madison, Home Depot, Target... – SnakeDoc Oct 29 '15 at 21:38
  • @Freedo, I'd like to add: some people email themselves from their other email accounts from time to time, so you may not be able to reset those passwords if they aren't using the same email account. It may take some light detective work. I just wanted to show how bad it could get in as many examples as I could think of at the moment. – Mark Buffalo Oct 30 '15 at 01:23
  • 1
    I think you could have used the term [rainbow table](https://en.wikipedia.org/wiki/Rainbow_table) in your answer. I don't think a traditional SQL database is used for this task though. ;) – joeytwiddle Oct 30 '15 at 10:24
  • Of course. A traditional SQL database would be used if you wanted to store all of the results online for others to check. :) Have you seen those sites? – Mark Buffalo Oct 30 '15 at 20:14
  • I forgot how narrow minded some security folk can be. Some sites have been there for years and just because they've been left unsupported doesn't mean the owner is going to be subject to a lawsuit (from the wording I'm guessing we have a lot of US people on this board and I guess the suing culture is more prevalent there). If you read some of the stuff written on here then no-one should be allowed to put a website up unless they have sufficient resource to spend chasing down every potential security issue... business is about balancing risk when it can't be removed completely – Steve Oct 31 '15 at 19:13
  • You're really shooting yourself in the foot if you decide not to protect people's information. =/ – Mark Buffalo Oct 31 '15 at 22:22
  • 2
    @Steve What did you expect? You came here asking if all of the industry standards, recommendations, and best practices are really just BS and if you could just ignore them. Why do you think people reacted the way they did? From your comment, you just dismiss all this as people being paranoid. Seriously guy, do the work right or don't do it at all. Don't be the guy that gives the industry a bad name because you're too lazy or too incompetent to do the job correctly. – SnakeDoc Nov 02 '15 at 16:45
  • I honestly don't see where this got out of hand until you made those accusations. I thought it was a good question, and one that really needed to be answered. Maybe you misunderstood us? – Mark Buffalo Nov 02 '15 at 16:47
  • @MarkHulkalo I think people are getting sick and tired of seeing this same question in various forms over and over, asked by some person who thinks they are so clever they can just do it their way and flagrantly ignore all industry best practices. – SnakeDoc Nov 02 '15 at 16:48
  • 1
    To be clear. I understand and agree with all that's being said and am working on sorting out sites which have the budget to have this corrected. My point really is that some sites don't have any budget and/or are old and the data isn't really valuable. The question then is delete the site and stop the business OR accept a partial solution... and that's not my call. All I was really pointing out was that this is a real decision and just shouting imbecile at me isn't acknowledging reality. I see comments that this is an hour's work... believe me it's not when you are working with Classic ASP! – Steve Nov 09 '15 at 13:49
19

A common type of breach is read-only access to the user table. This is because this table is used in the code that does the login for which you don't need to be already authenticated. Gaining the passwords would then allow read-access to all data. But even if the attacker already has full read access on the DB he can still gains write access through the passwords, being able to log in to the account and easily change some data.

Selenog
  • 984
  • 4
  • 8
  • 1
    Not even always a breach - in old school *nix systems (those not implemented "shadow passwords") , every logged on (unprivileged) user has such access. – rackandboneman Oct 29 '15 at 14:54
10

One very simple reason for salting and hashing users' passwords is this:

A user's password is his/her secret

No one else should know it. Not you, not your colleague, not the DBA. No one. Simple as that...

user90546
  • 109
  • 2
  • In your opinion... operationally in some circumstances you need to "become the client" but since this is a security site I expect that operational logic isn't highly rated! – Steve Oct 29 '15 at 17:21
  • 14
    If you have administrative access to a (properly-designed) system, you can "become the client" without knowing his password. I have never had to ask someone for their password to be able to test what their account could do; I just use `sudo` (or its equivalent). – Monty Harder Oct 29 '15 at 18:13
  • 2
    @Steve You know how all those big services always tell you to never tell your password to anyone, even if they sound like they're from $SERVICE support? – Blacklight Shining Oct 30 '15 at 22:43
  • 3
    @Steve: just add some functionality to your site that shows you the site as user $USER would see it, only available to admin users. No need to use an actual login. – RemcoGerlich Oct 31 '15 at 07:30
6

Part of salting is to make analysing and stealing the password and use their username/email and password combination on other sites more difficult.

It's fairly common for users to re-use 1 or 2 passwords on multiple sites. Changing your algorithm to one that salts and takes a bit more time (eg. bcrypt, scrypt, and similar) is highly recommended, and fairly simple to implement in most languages.

Thor Erik
  • 171
  • 5
1

The purpose of a salt is two fold: first, it introduces a unique(-ish) element to each password, so that if two users happen to use the same password, the hashed text of the password will vary. If User A sees that her password hash is "QWERTYU123", and that User B's password hash is also "QUERTYU123", then User A can deduce that she has the same password as User B.

Secondly, it introduces a significant speed bump to anyone with access to the database who wishes to brute-force the passwords with a dictionary attack. Without a salt the attacker can simply hash "TRUSTNO1" to get the hash "QUERTYU123", then scan the password column to see if that text appears. With a salt, the attacker has to rehash "TRUSTNO1" for each and every row in the database in order to test for a match, adding significantly to the amount of CPU required to check each dictionary entry.

SEM
  • 11
  • 1
1

if they have access to the database then they don't actually need the password(s) as they can just steal the data direct from the database

The password is the valuable thing. That is because many, many people re-use the same password. So the password to your pigeon club could be the same one they use for their online banking.

I look after a system which holds a lot of "low grade" information, nothing financial but name/address/email etc.

These are valuable too. I've lost track of the number of emails I have received recently from "eBay" or "Apple" claiming my account has been limited unless I "verify" my details. They are usually obviously fake because they don't mention my real name. But if you store a name and an email address it is much easier to make a realistic-looking mail-out, asking for more personal information. For example:

Dear Mr. Smith of 42 Station Street, Gotham City.

We just realized our club overcharged you this financial year and would like to reimburse you $10. Please reply with your banking details so we can deposit the money to your account.

So, don't dismiss emails and names.


The bottom line is, though, that hashing and salting your existing database should only take roughly an hour of coding and testing. Then you can do a "batch convert" of the plain-text passwords to the hashed and salted ones.

Nick Gammon
  • 1,197
  • 7
  • 15
0

Encrypting user information like name, email, etc. and storing in database rather than storing it in a raw format provides an extra level security to your application. Secondly people having access to your database also can't read data easily. Any kind of information that you store which come from any customer has it's secrecy. As it's their data and it's a developers responsibility to store it in a manner that makes it difficult for the hack to make meaning be it low grade info or top secret info. Also,Decrypting and encrypting data should be done at server side as generally servers are kept behind firewall. So it becomes more secure from security perspective.

0

I can see what you mean if the attacker were able to access the database as well. The thing is though, a well designed security system will only let the database store information that both the user and the server have encrypted individually.

Generally, the password is the first lane of hidden values in which you can have your users give that can be hashed to decrypt their data in order to provide a second layer of security if the database's encryption keys are ever compromised. That way even when there is a breach, the user's data is still safe.

codykochmann
  • 277
  • 1
  • 6
0

In this context, the point of hashing is based on the idea of a one-way, or trapdoor, function: a function that's easy to compute but hard to reverse. When the user generates a password, the system computes its hash and stores that value in the database. When the user submits a password to get entry to the system, it computes its hash and compares it to the value in the database. If they're the same, great; if not, then the password was wrong, and the user should be prevented from accessing the system. In order to make this work, the hash needs two properties: (1) Different original values hash to different values; (2) It's computationally difficult to go from the hash to the original value.

So, why bother with hashes at all? If someone hacks into your database (not just by computer hacking, but by social engineering attacks, leaving a print-out on the bus, acts of a disgruntled employee, etc.), all they get is a series of hash values. It's hard to recover the original value from a hash value, so this is not very useful to a hacker. If the plaintext passwords are stored in the database, then the hacker wins if the database is compromised; he has direct access to all the accounts and passwords, and he can basically do whatever he wants. This setup also means that you don't have access to people's passwords. This is a good thing; even if you trust yourself, you presumably don't trust--- and shouldn't need to trust--- your counterpart at your bank, your predecessor or successor at work, etc. You shouldn't have to depend on the largesse or whim of an adminstrator in order to ensure that your information is secure.

As for salts, I mentioned above that hashes have to have two nontrivial properties in order to be effective. (There are some additional ones I'm skipping over for now.) Functions having those properties are nontrivial to find, and it would be unwise to rely on the particular administrator of a site to come up with a decent one. Instead, there are widely available hashes that most people use. The point of a salt is to ensure that different sites effectively use different hashes: instead of just hashing 'password', we instead 'salt' + 'password' for various values of 'salt'. This means that if someone uses the same password on two sites, they actually have different hashes on the two systems, so that a hacker can't use one to break the other. Also, without the salt, hackers could just brute force all the hashes for passwords of a reasonable length. I mentioned above that hashes need to be difficult to reverse. If you have a table of all the possible hashes for passwords up to, say, 10 letters (or even just the most commonly-used passwords), then it's trivial to reverse the hash; just look it up in the table.

anomaly
  • 101
  • 1
0

In addition to the other answers, keep in mind there are many degrees of vulnerabilities between completely secure and full access to a database. A vulnerability might expose only some passwords, or only the first few characters of it, or be difficult to associate with a particular user, etc. Hashing and salting can keep a minor breach from turning into a major one.

Also, intruders like to limit their own exposure. The longer they use a vulnerability or back door to get into a system, the more likely they are to get discovered and locked out before accomplishing their objective. If you leave your passwords unhashed and unsalted, you've just given them a very easy way to get back into the system posing as any user, that is extremely difficult to detect and mitigate.

Karl Bielefeldt
  • 423
  • 2
  • 8
-2

I think the best way of putting this is: the year is 2015, the most private and personal information your users are entrusting to you is their password and user id. Protect it, not with your life but with your ignorance, not with your ability, but your inability.

If you do not know their password and have no way of recovering their password, then no one can steal it from you or force you to divulge it.

Any competent digital thief, given a choice between a thosuand names and addresses and a thousand email addresses/usernames and passwords, will take the later every time.

I understand about cost and time, but if done correctly, from the start, it really doesn't take any extra time at all, and switching to a more secure method isn't that time consuming.

jmoreno
  • 496
  • 2
  • 9