How does nonce verification work?

The question:

I can see that wp_nonce_field generates a value in the hidden field.

<input type="hidden" id="message-send" name="message-send" value="cabfd9e42d" />

But wp_verify_nonce isn’t using that value as far as I can tell, but I may be wrong.

It looks like it’s using a session token for verification.

$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10 );
 if ( hash_equals( $expected, $nonce ) ) 
  { return 1;  }

Then what’s the point of having a value attribute in the hidden field?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

TL;DR

In short, wp_verify_nonce() uses that value because it expects that value as its first argument.

wp_verify_nonce() arguments

wp_verify_nonce() receives 2 arguments:

  1. $nonce
  2. $action

The value in the hidden field ('cabfd9e42d' in your example) represent the $nonce.

1st argument is the nonce, and comes from the request

In fact, wp_verify_nonce() have to be used like so:

// here I assume that the form is submitted using 'post' as method

$verify = wp_verify_nonce($_POST['message-send']);

So the first argument passed to wp_verify_nonce() is exactly the value that is present in the hidden field.

2nd argument: the wp_create_nonce() method

Regarding the second argument, it depends on how you build the nonce value.

E.g. if you did:

<?php $nonce = wp_create_nonce( 'custom-action' ); ?>
<input type="hidden" name="message-send" value="<?php echo $nonce ?>" />

Then you need to do:

$verify = wp_verify_nonce( $_POST['message-send'], 'custom-action' );

So, the second argument is what was used as argument to wp_create_nonce().

2nd argument: the wp_nonce_field() method

If you created the nonce using wp_nonce_field() like:

wp_nonce_field( 'another_action', 'message-send' );

Then you need to verify the nonce like so:

$verify = wp_verify_nonce( $_POST['message-send'], 'another_action' );

So, this time, the action is whatever passed as first argument to wp_nonce_field().

Recap

To pass wp_verify_nonce() validation you need to pass 2 arguments to the function, one is the value in the nonce hidden field, the other is the action, and depends on how the nonce value was built.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment