Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WordPress not refreshing nonce token on the server

I have a form in my plugin similar to this:

<!-- Client form -->
<form>
   <?php wp_nonce_field('my_form','_my_token'); ?>
   <!-- Additional form fields -->
</form>

it generates those two fields:

<input type="hidden" id="_my_token" name="_my_token" value="abcdefghij" />
<input type="hidden" name="_wp_http_referer" value="/wp-admin/tools.php?page=my-plugin%2Fplugin.php" />

When I submit this form, I validate it like this:

//Server's side check
if(!wp_verify_nonce($_POST['_my_token'],'my_form')){
   echo 'Invalid token! Expected token: '. wp_create_nonce( 'my_form');
   exit;
} 

The problem is that on the server, token never changes, it's always the same, and validation always fails in this step. If I log out from WordPress and then log in again, on the client token has changed, but on the server it's the same.

I've tested this locally and when I log in again it always changes token on both sides, but on my production environment it only changes on the client side.

It looks like it's cached somehow, but not sure what exactly could be. I've used WP Super Cache plugin, but it's now disabled and this issue persisted. I have multisite feature enabled on my production site, but I don't believe that's related to it. Any ideas?

like image 980
gradosevic Avatar asked Mar 16 '16 10:03

gradosevic


People also ask

Where is WordPress nonce stored?

WordPress uses NONCE_SALT and NONCE_KEY to generate unique nonces. These nonce salts and keys, along with other unique keys are stored in wp-config. php file and are unique to each WordPress site.

How long does a nonce last?

By default, a nonce has a lifetime of one day. After that, the nonce is no longer valid even if it matches the action string.


1 Answers

What is the time frame on which you are expecting your nonce to change?

On successive refreshes with no other changes the nonce may be identical between page loads. Basically, if you sit there and hit F5 you're going to get the same nonce.

This is by design. Idempotent creation of nonces within a short time frame is required in order to use them for validation.

Once again, basically, if this didn't work this way you'd never be able to verify your nonce. When you created it, the value would be one thing and when you went to re-create it to verify it the value would be another. Validation would always fail.

wp_verify_nonce() may accept a nonce (all else equal) for up to 24 hours (see the WP Codex page). You may need to wait a longer time than that to receive a different nonce.

Other system events that can occur can cause a new nonce to be generated. I have never needed to do this myself but it appears that you may use wp_nonce_tick() to jog this process.

It is possible that either or both wp_create_nonce() (used directly by wp_nonce_field()) and wp_verify_nonce() may have been re-written by some plugin as they are both defined in pluggable.php and intended to be available for override. A well-written WP-aware CDN or other cache solution may do exactly that to persist sessions. I do not know if Super Cache does this or not.

Alternately, and if your system configuration doesn't do so already, you may choose to rewrite those functions yourself. This would be security code and be careful writing security code: the greatest saving grace of open source security code is that it is peer-reviewed and your (new) code will not likely be the same.

like image 56
Stephan Samuel Avatar answered Sep 26 '22 14:09

Stephan Samuel