When installing a fresh wordpress, one of the things one should do is, updating the salts in wp-config.php.

The section looks like this

define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

If the client does change these salts or the constants are missing, wordpress will on save these values inside the database instead.

For generating the the salts it uses wp_generate_password(64, true, true) The code doing this can be found in pluggable from line 1993.

Now the question is :

  • Is wp_generate_password as safe as the salts generated by the recommended https://api.wordpress.org/secret-key/1.1/salt/

  • Is there any downgrade in security by having the salts in the database as this method falls back to that.

  • Does it have any security implications to not set the values and let them be generated randomly on the fly to the db?

3 Answers 3

  1. Is wp_generate_password() as safe as the salts generated by the recommended https://api.wordpress.org/secret-key/1.1/salt/?

Those details can't be answered as for obvious reasons, the internals are unknown by the public. If we could answer that, then details would be known that allow for reverse engineering the process. This could lead to a decrease of security. Note, that someone could still try to set a gazillion of requests to this Url and then try to reverse engineer the process from watching what bubbles to the surface.

  1. Is there any downgrade in security by having the salts in the database as this method falls back to that?

Yes. You do not want to have security details/authentication credentials saved anywhere where it might be accessible by others. This includes:

  • Version control
  • Command line history
  • Database or file backups

Either keep your authentication credentials and related data (like for e.g. "salt") in .env files (see Dotenv package), in your deployment services secret secure haven, in separate configuration files (for e.g. AWS credentials file) and therefore in only a single location.

  1. Does it have any security implications to not set the values and let them be generated randomly on the fly to the db?

Yes. As auth constants are used in Cookies as well, you would invalidate your users log in sessions by invalidating your users Cookies. Those are constants for a reason: They should stick and do not change per request.

Edit: As @gmazzap pointed me to it, I was not talking about values saved to the database, but about "generated on the fly" constants. In case you save it to the database, please refer to point 2 regarding security.

For further additions, please follow the link from @Mark Kaplun and read @gmazzap answer in detail (and upvote both).

Additional Note/Reminder: Always add some own pseudo random characters to the retrieved data from the API servers. And never ever give your credentials or your database out of hands. You won't believe what people tend to email, save on usb-sticks, their private dropbox accounts or on hard disks on laptops without password…

Edit: As @stephenharris pointed out in [chat], there's an interesting blog post around that topic that goes in far more detail than our answers here.

  • I'd like to mention Kerckhoffs's principle here: "A cryptosystem should be secure even if everything about the system, except the key, is public knowledge." So even if all the details were known by the public, the system should still be save.
    – Jan Beck
    Commented Mar 2, 2016 at 7:29

Is wp_generate_password() as safe as the salts generated by the recommended https://api.wordpress.org/secret-key/1.1/salt/

As @kaiser said the internal details of API salt generation are not known, but -honestly- the API returns a 64 character string where each character is one of the same 92 possible glyphs used by wp_generate_password().

Note that if the server has PHP 7, random integers used to pick one of the 92 glyphs is generated using PHP 7 CSPRNG and I doubt that API will have something more stronger that that. In older PHP versions, random values are provided by mt_rand.

Considering this, and considering that strongness of a password resides much more on the encryption algorithm then on the salt used, I can say that, yes, wp_generate_password is very likely as safe as the salts generated by API.

Is there any downgrade in security by having the salts in the database as this method falls back to that.

For this point, I agree with @kaiser.

Let's assume that someone get a copy of your database dump, done for a backup. In that db dump, they can see your users passwords, but encrypted.

If they have access to salts, is easier to them hack your website.

Moreover, by knowing salt used, user IDs and user metas (where session tokens are stored), is very easy to reproduce nonce values for any of the users, without having to know the "decrypted" password.

Of course, if a malicious user obtains a copy of your database, your security is very compromised anyway, but by storing salts in db, you make life of that malicious user easier.

Does it have any security implications to not set the values and let them be generated randomly on the fly to the db?

If salts aren't set at all, they are generated with wp_generate_password() only the first time WP tries to access them, then are stored to database and on subsequent requests, they are pulled from there.

As mentioned earlier, salts generated by wp_generate_password() are not bad per se, but since they are stored in db, the secutity implications are what said in previous point: if someone has access to a copy of your db, it is more dangerous if that db copy contains the salts.

However, the real security implications are when non-secure values are used for salts. In fact, if weak values are set in configuration, WP will not generate any value, but will use that weak values.. In short, if the choose is between no salts in configuration and weak salts, the former is surely better.

Note that in recent versions of WP (not sure since which exact version) the default value 'put your unique phrase here' is ignored, so if wp-config.php contains that value for any salt, WordPress will ignore it and use a value generated with wp_generate_password() that is better than a weak value, but worse than a strong value stored in config (because storing salts in db...). Automatically generated values are used even in the case that the same salt value is used for more than once salt.


  • A change in salts will logout any user logged in your site before the change, including those users that are not logged in in the moment you change but that choosed "remember me" option when logged in before the change.

  • When WordPress is installed using the "installer" (without manual creation of wp-config.php) salts values are generated pulling values from API.

  1. It depends on the randomness that can be achieved on your machine. I don't remebmer the exact details, but the wordpress.org API is there if the randomness of your machine is not good enough.

  2. Probably not. If someone has that kind of access to your DB or code then you are toast in any case and getting the salts is the least important problem you face.

  3. What would be a reason to do that? getting those 8 values from the DB will make every page being served very slightly slower without adding any value to your security.

Edit: why randomness (entropy) matters

first, maybe this https://security.stackexchange.com/questions/61676/why-do-wordpress-installations-retrieve-the-crypto-secrets-remotely-on-installat will explain it better then me

The issue is that salts should not be guessed, therefor they are generated by relaying on some random number generator, which most OS has. But not all random generators are created equal and if for example your generator do not take as an input some values from the enviroment it will generate the same sequence of numbers and therefor anyone which inspects the behavior of the OS can come up with say the first 1000 numbers that are going to be generated, use them as salts, and have easier time guessing your password.

This is especially problematic in a shared hosting enviroment where all sites use the same random generator, and therefor have access to the sequence of the randomly generated numbers and based on the knowledge of the OS and the random algorithm employed by it can guess the next and previously generated numbers.

side note: this is the reason why smartphone and other software asks you to do some random input when initializing the devices/software. That random input serves as a base for random number generation and ensures that each device will generate a different sequence of numbers.

The advantage of using wordpress.org as your random number generator, is by knowing that the numbers generated by it are impossible to guess without access to the servers as you don't know which algorithm, is being used, how it was initialized and where in the sequence you currently stand.

But as the question I linked to says, relaying on external service is also a security problem. I find this to border paranoia as this kind of attack avenue requires sophistication most attackers lack (in the context of attacking wordpress sites), and I would not worry about the quality of the random generator, but if you do, all you have to do is generate the salts by yourself, maybe by using some random generator software which is not related to the server, and update the config file.

  • Could you please explain what "if the randomness of your machine is not good enough" is in detail? Would be interesting to know what increased randomness there could be. Thanks in advance.
    – kaiser
    Commented Feb 29, 2016 at 1:00
  • @kaiser, hopefully I am more clear now Commented Feb 29, 2016 at 2:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.