Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Is wp_nonce_field vulnerable if you know the action name? I am actually adding a hidden field with name = the name of the action name in my form so that my plugin can identify it. I want to know if there's security issues if I am making my action name "visible"?

edit: I am actually automating my form submission workflow; so if displaying the action name is a concern, i can encrypt it. ex. I call MyFormPlugin::generateAction( 'submitQuestion' ); in my form to generate the nonce and my hidden "form_action" action field.

class MyFormPlugin{

    public static function generateAction( $action, $referer = true ){
        $nonce_field = wp_nonce_field( self::secured_action( $action ), "mfp_nonce" , $referer , FALSE );
        return $nonce_field.'<input type="hidden" name="form_action" value="'.$action.'"/>';
    }

    public static function secured_action( $action ){
        return md5( $action.'randomsalt');
    }

    public function verify_nonce( $action ){
        $nonce = $_POST[ 'mfp_nonce' ];
        return wp_verify_nonce( $nonce, self::secured_action( $action ) );
    }
}

does this look secured?

share|improve this question

1 Answer 1

up vote 4 down vote accepted

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.

share|improve this answer
    
thx for the detailed explanation. So, i should not reveal the action name to the user? (I am md5'ing it anyway when generating my nonce) It's a creation form, i can't append an id to it. –  yeahman Apr 20 at 10:34
1  
No, I think you misunderstood my reply. It doesn't matter whether the user knows the action name or not, and you don't (and shouldn't) need to md5 the action name either. The users knowledge of the action name is wholly irrelevant. –  Otto Apr 20 at 15:07
    
ok but i don't understand the part where you say actions should be a unique as possible –  yeahman Apr 20 at 15:38
    
They should be unique in their action name (not the same as something used by core or by another plugin, etc), and they should include an identifier of whatever they are operating on, if they are operating on some thing. A "create_thing" action which is creating a new thing would not have such an identifier. –  Otto Apr 20 at 16:02
1  
Yeah, any identifiers you use with a plugin should ideally be prefixed with the plugin's name/slug. –  Otto Apr 21 at 9:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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