Is wp_nonce_field vulnerable if you know the action name?

Short answer: No. You can use normal strings for actions, md5’ing them doesn’t change anything.

The nonce is built from three main pieces of information:

  • Time: The current time() divided by 43200 is worked into the nonce. This is what lets the nonce be changed every 12 hours (43200 seconds in 12 hours).

  • The action string you provide. More on this below.

  • The user ID. Every user gets different nonces.

Now, these elements are concatenated, and then the nonce itself is (a smaller piece of) the wp_hash() of this combined string. The wp_hash() function automatically salts the hash, in this case using the NONCE_KEY and NONCE_SALT constants, which should be defined in your wp-config.php file, and which should be unique to your particular site.

(Note that if you happen to have the default of “put your unique phrase here” in that file for whatever reason, WordPress generates random 64 character values for the keys/salts internally and stores them in the database. It won’t use the default values as actual salts. It also won’t let you use duplicate keys or salts for any of the values. Still, you should have the keys and salts defined in the wp-config.php file, and not rely on this. You can get randomized lines for that file from here: https://api.wordpress.org/secret-key/1.1/salt/)

So in order to duplicate a nonce, you need all this information. Time and user ID can probably be deduced. The action string may be known. But the salt is a secret value that should not be known by an attacker, and this makes it infeasible to duplicate the nonce.

That said, the “action” string should be as unique as possible to the specific case. It should be different for each action, like delete_thing vs. update_thing vs. create_thing. And it should contain some “ID” if it is acting on a specific thing, so like “delete_thing_123” for that specific thing.

It doesn’t necessarily add any real security to include complex data in the action string, like the MD5 hash of something. The nonce is already built using the HMAC message digest method with salted secret values. But, the nonce will be the same for the same action, so the action should be specific to the case, in order to make the nonce unpredictable across multiple cases. A nonce used to delete one item won’t delete any item, type of thing.

Also be aware that action values to generate nonces should be entirely internally generated. In no case should user input be used to determine the action which generates the nonce. If a user can inject data to determine the action string, then they can get nonces in advance. Nonces need to be unique static strings with possibly ID’s concatenated to them.

TL;DR: Use a plain string with an ID (if having an ID makes sense). It’s just fine.

Leave a Comment