Home > PHP Security > PHP Security – Weak salt vulnerabilities

PHP Security – Weak salt vulnerabilities

Salt is good; but if the salt becomes unsalty, with what will you make it salty again?

- Jesus

Salting your hashes is a good thing.  It adds another level of protection to your hash, and prevents the effectiveness of rainbow tables should your hash get out.  It’s been standard practice to use a salt when storing passwords and similar information for almost 30 years now.  Using a weak salt can significantly reduce the protection it will give you.  Also, use of a salt should just be an additional level of protection to your hashes – not your only protection.  However, the use of a salt doesn’t suddenly mean that sharing your hashes with the world is a good thing.

Not too long ago, I was reviewing the code on a smaller open source CMS. I came across this block of code

function setUserForeverCookie() {
$hashVal = md5(PASSWORD_SALT . $this->getUserID());
setcookie("ccmUserHash", $this->getUserID() . ':' . $hashVal, time() + 1209600, DIR_REL . '/');
}

What function does is create a forever login cookie value out of an md5 hash of the combination of your user id and a static PASSWORD_SALT value.  The PASSWORD_SALT value is a number between 100,000 and 999,999, created upon the installation of the CMS.  The user id is a publicly availble id used to identify the user throughout the site, such as in the URL to the user’s profile page.  For the default super admin, the user id is always 1.

By creating an account and getting your own forever login value, you could easily discover this weak salt.
for ($i = 100000; $myForeverLogin != $guess; $i++) {
$guess = md5($i.$myUserId);
}

echo "Salt is $i\n"
echo "Admin cookie is ".md5($i.1);

In seconds those few lines of code will give you the server salt and the admin’s forever login cookie, giving you full control of the site.

While the use of something like a forever login cookie inherently poses some security risk and is prohibited from use in such regulated industries as financial or healthcare (you always need to login when you visit your bank, for example), there are times that it’ll come up as a requirement and it might make sense to do with your web app.

A better implementation of a forever login would combine a stronger salt with a number used once, or nonce, which would be stored in the database with a user record. A stronger salt would be something like a 32 character key of random letters & numbers. The hash algorithm probably wouldn’t be md5 either, and instead use a stronger encryption algorithm. By using both a strong salt stored outside of the database and a nonce in the database, a breach of either the code or the database alone would not allow a user to create a forever login.

Categories: PHP Security
  1. No comments yet.
  1. No trackbacks yet.