What is the Security Risk of Giving Away Both the Salt and Encrypted Password? - security

I have inherited an app to maintain and I just discovered that when a user logs in, the returned JSON from a successfully login contains:
Primary Key of the User record in the DB
User Name
Encrypted Password
The password's Salt
It seems that having the Salt and Encrypted password voids the purpose of the salt in general.
A brute force or lookup table attack is now available again as a cracking approach.
Am I correct on this, and is there more of a threat than just that?

It's not the greatest but it is generally OK to disclose the salt. You're thinking of a pepper, which is to be kept secret.
The salted hash is not meant to prevent a brute force attack. It is meant to prevent a rainbow attack. By including the salt in the input value to the hashing algorithm, it becomes impossible to precompute lookup tables, unless the hacker creates a lookup table for each and every possible salt.

In my opinion, even when it's not something like giving away a password, you're giving away information that your front-end will not need at all and that could lead to an attacker getting the password! I mean, yes, if an attacker gets that information, he still needs an exhaustive search, with all the possible password combinations concatenated with that salt (or hashing a password dictionary with that salt), but you're giving him resources for an offline attack, and now he can try as much different passwords as he wants until he gets bored, or he gets the real password.
Someone may be thinking that it's the same as an attacker trying to authenticate with different passwords, but the main difference, is that in an online attack, you can limit the number of login attempts, so he'll not be able to try as much as he wants, while in an offline attack, he can try as many passwords as he wants.
All this could be avoided by just sending a boolean, instead of the full object and since it's not like it will require a huge refactory or something like that, I think that it's something that needs to be fixed (and you should also take a look at what he does with that information, in the worst case scenario, he's retrieving the password's hash to store it in a cookie or local storage to keep authenticating the user, or something like that).

If the salt & hash is only available from a POST to the login handler, then the damage here is very limited.
If there is some webmethod (/currentUser/getDetails) that returns the data, then this is a risk should their be any Cross-Site Scripting (XSS) vulnerabilities elsewhere on the site. Any attacker could call this method via the XSS, and then retrieve the hashed password and salt for offline cracking.
Another low risk is if the JSON response does not output anti-caching headers then another user of the same computer may be able to retrieve their password hash.
I am more concerned that the password hashes are in Hash(Password+Salt) format, rather than in a format using a secure algorithm such as bcrypt or pbkdf2.

Related

Security implications of generating salts immediately vs. when needed

Say I have a database of users (customers). Some of these customers have logged in through a portal, some of them have not and only exist in the database to facilitate customer management by an administrator. At a later date, customers may decide to begin using the portal, at which point they'll need to be provided a password.
Assuming the randomization method is reasonably secure, are there any security implications related to the timing of the salt generation?
ie.: is it better, worse, or irrelevant to be salting all accounts as early as possible vs. salting only at the time a password is created?
The main idea behind the salts, is to offer protection against rainbow tables, which are databases containing pre-hashed passwords. Having each password salted using a different salt allows you to minimize this risk, since now (in theory) there should be no rainbow table containing your password.
As long as you're using a cryptographically secure pseudo-random number generator (CSPRNG) to generate your salts, there should not be a problem with salting your passwords as early as possible (and it'll be even better if you use the salting mechanism already included in most modern implementations). After all, you only care about always producing a different hash. And salts are not even secret values, if your database got compromised, the attacker will already have the hashed password and the salt (they're usually stored like salt$base64HashedPassword, or they just have a column for the salt), and salts are not like the IVs in cipher block chaining (CBC) where an attacker can take advantage of a predictable IV. Here you only care about always producing a different hash, so as long as you do it, everything should be ok.
Edit: Now I'm curious about something. You're talking about salting the password someday in the future... does that mean that you're storing it as plaintext or in a recoverable way before salting it? Because now that'll be a bad practice. You need to salt it as soon as you get it, since you should not know anything about user's passwords.

does hashing suffice encryption

does using hash functions and algorithims suffice the need to encrypt the data, while communicating with the server
I am applying salt mechanism in my project and I will be concatenating the salt with the entered password, and then hash them all.
do I still need to encrypt the result?
The usual workflow for a website to transmit user passwords looks like this:
The client sends the password plaintext to the server.
The transmission is done with an encrypted connection (HTTPS/SSL), to prevent a ManInTheMiddle attack.
The server calculates a hash of the plaintext password, and this hash is then stored in the database. It is not necessary to encrypt the hash any further.
Make sure you use a random unique salt for each password, and a slow hash function with a cost factor for hashing passwords. Good algorithms are BCrypt, PBKDF2 or SCrypt.
Storing passwords
To store user passwords securely, you need 3 things:
Do not store the plain password, store a hash instead
The hash makes it extremely difficult to recuperate the password even if an attacker manages to capture the entire database
To prevent the use of rainbow tables, you need a salt
The salt is stored in the clear (can be along with the hash) and is random, one for every user and you can easily chose a few one whenever the user changes their password.
You need a SLOW hash, not a fast hash
What are fast hashes: MD5 (consider it broken), SHA-1, SHA-2, ... are unsuitable as the attacker can perform them too fast and use dictionary attacks to try common passwords and find that way up to 95% of you user's passwords in mere hours on modern rigs.
How slow does it need to be ? As slow as you can afford.
And there's a rule 0: Do not invent crypto yourself, you will make serious mistakes before you know it.
Other privacy sensitive info
You're most probably also storing other sensitive information of your visitors in addition to the passwords (email addresses, IP addresses, names, postal address, ...), CC numbers (you better not go there), ...
You need to protect that as well and using hashes isn't the way to do that in most cases. Some of these have requirements and regulations of their own (e.g. Credit Card data is regulated by the issuers who'll force you to be compliant with PCI-DSS).
In essence you need to do a risk analysis and manage that risk by either accepting it ("so be it"), transferring it ("get insurance"), avoid it ("we're not storing that"), or mitigating it ("we're going to improve our way of working").
encryption
Why the media will make you believe there's a "magic" solution in that incomprehensible "encryption" thing, in reality it needs to be done right and in the right conditions to have any meaning at all.
E.g. If you encrypt the entire disk of a server: it will not protect you from an attacker abusing your server scripts and getting to the database (as the database engine and webserver scripts have access to the decrypted disk already)
So, you really need to go back to the risk analysis and chose the measures there instead of getting ahead of yourself and suggesting encryption as a tool that's unlikely to help you for your biggest risks.

How passwords are secured while registering it?

I have read the following article http://lifehacker.com/5919918/how-your-passwords-are-stored-on-the-internet-and-when-your-password-strength-doesnt-matter
There are a number of ways a site can store your password, and some are considerably more secure than others. Here's a quick rundown of the most popular methods, and what they mean for the security of your data.
Method One: Plain Text Passwords
How It Works: The simplest way a site can store your password is in plain text. That means somewhere on a their server, there exists a database with your username and password in it in a human-readable form (that is, if your password is testing123, it is stored in the database as testing123). When you enter your credentials on the site, it checks them against the database to see if they match. This is the worst possible method, in security terms, and most reputable web sites do not store passwords in plain text. If someone hacks this database, everyone's password is immediately compromised.
Does My Strong Password Matter? No way. No matter how long or strong your password may be, if it's stored in plain text and the site gets hacked, your password is easily accessible to anyone, no work required. It still matters in terms of hiding your passwords from, say, your friends, or others that could easily guess it, but it won't make any difference if the site gets hacked.
Method Two: Basic Password Encryption
How It Works: To add more protection to your password than plain text provides, most sites encrypt your password before they store it on their servers. Encryption, for those of you that don't know, uses a special key to turn your password into a random string of text. If a hacker were to get hold of this random string of text, they wouldn't be able to log into your account unless they also had the key, which they could then use to decrypt it.
The problem is, the key is often stored on the very same server that the passwords are, so if the servers get hacked, a hacker doesn't have to do much work to decrypt all the passwords, which means this method is still wildly insecure.
Does My Strong Password Matter? No. Since it's easy to decrypt the password database with a key, your strong password won't make a difference here either. Again: this is in terms of the site getting hacked; if you have a nosy friend or family member rooting through your stuff, a strong password can help keep them from guessing it.
Method Three: Hashed Passwords
How It Works: Hashed is similar to encryption in the sense that it turns your password into a long string of letters and numbers to keep it hidden. However, unlike encryption, hashing is a one way street: If you have the hash, you can't run the algorithm backwards to get the original password. This means a hacker would have to obtain the hashes and then try a number of different password combinations to see which ones worked.
However, there is a downside to this method. While a hacker can't decode a hash back to the original password, they can try many different passwords until one matches the hash they have. Computers can do this very fast, and with the help of something called rainbow tables—which is essentially a list of trillions of different hashes and their matching passwords—they can just look up the hash to see if it's already been discovered. Try typing e38ad214943daad1d64c102faec29de4afe9da3d into Google. You'll quickly find that it's the SHA-1 hash for "password1". For more information on how rainbow tables work, check out this article by coding guru Jeff Atwood on the subject.
Does My Strong Password Matter? In this case, yes. Rainbow tables are made up of passwords that have already been tested against hashes, which means the really weak ones will be cracked very quickly. Their biggest weakness, however, isn't complexity, but length. You're better off using a very long password (like XKCD's famous "correct horse battery staple") rather than a short, complex one (like kj$fsDl#).
Method Four: Hashed Passwords with a Dash of Salt
How It Works: Salting a hash means adding a random string of characters—called a "salt"—to the beginning or end of your password before hashing it. It uses a different salt for each password, and even if the salts are stored on the same servers, it will make it very hard to find those salted hashes in the rainbow tables, since each one is long, complex, and unique. LinkedIn is famous for not using salted hashes, which brought them under a lot of scrutiny after their recent hack—had they used salts, their users would have been safer.
By reading the above article i have the following questions in mind
1.Even if i do not have the password,i still can intercept the message digest......i dont even need the password ...i will simply launch reply attack(ie. send message digest itself for authentication after intercepting it!!)
the solution to above problem can be solved by following way
a.server genrates a random string(usually known as challenge) to the user and asks him to encrypt it with his password .....
b.user enters his password,message digest of the password is created ,random string is encrypted by this message digest
c.this encrypted string is sent to server.
d.server also encrypts random string with message digest of user,checks it with encrypted string recieved from user,if both match,he is valid user..!
2.My question is If the hacker gets access to the database,he will get access to the messagedigests/even if he does not get access to database,he can still obtain message digest while intecepting communication link when user first registers to DB......how this can be prevented??
Even if i do not have the password,i still can intercept the message digest......i dont even need the password ...i will simply launch reply attack(ie. send message digest itself for authentication after intercepting it!!)
This shouldn't be possible.
The client should send the real password to the server. It should be encrypted using SSL.
The server should hash the password and compare it to the stored, hashed password.
the solution to above problem…
That is, more or less, part of what SSL does.
My question is If the hacker gets access to the database,he will get access to the messagedigests
This is a relatively insignificant problem. The passwords should be stored as hashes with varied salts. The original passwords are protected.
even if he does not get access to database,he can still obtain message digest while intecepting communication link when user first registers to DB
Only if SSL is broken.
User registration should always be done through an SSL tunnel, so generally when following best practice you never have to worry about man in the middle type attacks.

What is the best practise for where password comparison should be performed

When authenticating a user to a website, should the hash generation and comparison be done in the database or the website?
My argument is the website should pass the user supplied password (possibly encrypted by the web server) to the database. The database then re-encrypts it with the salt and compares the hash's. The database the responds to the web server whether the user's credentials are valid or not. This way, the very minimum ever leaves the database, essentially either a yes or no, none of the stored credential info. Downside is, the database has to do more work.
The other argument is that the work should be done in the web server. Here the web server would create the hash and request the stored hash from the database and compare. In this situation the salt needs to be passed from the database back to the web server for the hash to be created. but, work is shared as # of web servers increase.
Personally I see the second method as a potential security risk. Should the web server be compromised, salts and hashes can be requested from the database and easily cracked.
What is the best practise for performing the above operation? Am I overlooking/missing something?
Thanks
The first problem I suspect you will run into (and it's a big one) is that your database does not have a password hash function. Sure, it probably has MD5() and SHA1() but these are cryptographic hash functions. Does it have bcrypt() or scrypt() or PBKDF2()?
Using a cryptographic hash function rather than a password hash function is what meant that the LinkedIn passwords could be cracked so quickly. If you don't use one of the above functions then you will be similarly vulnerable if your hashes are leaked.
Going on to answer your question assuming that your database does support a password hashing algorithm (using bcrypt simply because I have to pick one). The two alternatives are:
Hashing in the database:
$db->query("SELECT COUNT(*) FROM users WHERE username = '?' AND password = BCRYPT(?, (SELECT salt FROM user WHERE username = '?'))", $username, $password, $username);
if($row['count'] != 1)
{
// Not authenticated. Throw exception.
}
In this case, the raw password is sent to the database and a simple yes or no (1 or 0) is returned. This database communication can be encrypted. The hash and salt are never held in the application.
Hashing in the application:
$db->query("SELECT username, salt, password FROM users WHERE username = '?', $username);
if(bcrypt($password, $row['salt']) != $row['password'])
{
// Not authenticated. Throw exception.
}
In this case, the hash and salt are pulled from the database into the application and the hashing of the raw password and comparison is done there. The communication to the database can still be encrypted. The raw password is never held in the database memory.
For efficiency, we can assume that both hashing algorithms are written in C (or some compiled language) and are possibly provided by the OS so take the same time. The application hashing option receives more data over the wire and the database hashing option sends more and has a more complex query (essentially two queries, one to get the salt and one to effect the comparison). It may not be possible to use an index the way I have written that query but the query could be rewritten. Since the size of the data in both cases is likely still one TCP packet, the speed difference will be negligible. I would call this one a win for the application hashing option due to the subquery.
For exposure. I would consider the raw password to be more sensitive than the hash and the salt together. Therefore, limiting the exposure of the raw password seems like the safer bet, making application hashing the best practice.
There's a really good article on how to store passwords securely here:
http://throwingfire.com/storing-passwords-securely/
You are overlooking the purpose of a salt.
A salt is used to prevent a dictionary attack against hashed passwords. If your password is "peanut" and hashes to 12345, then I can pre-generate a list of hashes for every word in a dictionary (including your password) and quickly find your password by doing a lookup against my pre-generated set of password hashes. This is what happened to LinkedIn recently. If the passwords are salted, I'd have to pre-generate a dictionary for each salt value after compromising the database, which would be prohibitively expensive.
Furthermore, proper randomly-generated salts prevent an attacker from knowing that you and I have the same password (without the salt, we'd have the same hash).
My point is that the salts are not intended to be a secret. They are not public information, but an attacker getting access to the salt values + the hashes does not necessarily mean that the passwords have been compromised.
A good rule of thumb for computer security is that if you have to ask, you shouldn't do it yourself. But if your concern is exposure of password details if the web server is compromised, then one approach is to move authentication onto its own system, and don't give the web server access to the password database at all.

Why is it considered secure to store a random salt in a database with the user's password digest?

In the light of the big LinkedIn password leak, I've been thinking about password security. The web development frameworks that I have worked with in the past typically store a master, application-level salt as an app constant, then salt all user passwords with that value (randomly generated on a per-app basis). e.g. in pseudo-code: password = hash(App::salt + userPassword).
I've read a lot of advice that suggests generating a random salt for each user, then storing that in the database along with each user's password. My question is, how does this increase security? If an attacker procures a list of password digests from the database, they are likely also able to get the salt as well, right? Or is there some attack vector that I don't know of that will get password digests without access to the rest of the table?
Storing random salt for each user defeats Rainbow table attack.
In case of a "master salt" it is still possible to precompute such table and use it in the attack. With a per-user salt this becomes impractical.

Resources