WordPress and nonce for guest user

Questo articolo รจ stato scritto oltre 1 years, il contenuto potrebbe essere datato.

In a plugin for a customer I’ve added, for guest user, a system for unsubscribe to a certain feature and the logged user don’t need the nonce.

I’ve read about nonce in frontend that create some problems with a cache system but in my case is an internal feature.

I’ve implemented the nonces but doesn’t work, but the ‘action’ reference is the same but not the hash generated.

After some hours of debug, also of WordPress core, I’ve studied the nonce system of WordPress.

How to create a nonce

All the functions that generate the nonces:

  • wp_verify_nonce – Generate on the fly a nonce based on the action and compare the value
  • check_ajax_referer – Is for AJAX, check the environment and use the above function
  • check_admin_referer – Is for administrative screen, check the environment and use the first funtion
  • wp_create_nonce – Generate the nonce but we see shortly
  • wp_nonce_url – Add a _nonce parameter in the URL with value generated from the above function
  • wp_nonce_field – Create an input hidden field that use ‘wp_create_nonce’ as a value

The central function is wp_create_nonce that have a simple code.

For generate the key is created a string that combine: trick, action, user id and a token.

What is a tick? There is a good article about it.

What is a token? For logged user is the token of the session, for guest user is empty.

What is user id? The user id used in the system for unique reference of the user, for guest user is 0.

What is the problem?

As we can see if we generate the based key for the encrypted nonce contain the user id and the session key.

The guest user have empty values for these so what is the problem?

In my case I generate on the backend the nonce for guest user, the guest user use that nonce with a link (received by email) but the nonce generated on guest user is different.

What is the problem? The nonce is made for the same user that generate it.

Workaround

Copy the source code of wp_create_nonce and add empty value for the session and for the user id a zero value.

In this way the nonce is the same also for frontend, but for guest user the key have only a unknown value for attackers, the tick.

To improve the security for not guest user is only use a complicated action that contain data like email (the encrypted key use also the salt that you’ve defined in wp-config.php!).

With ‘wp_verify_nonce’ this workaround is compatible with ‘wp_create_nonce’ because use the same functions.

The code? Is on gist: https://gist.github.com/Mte90/a1b6443aabe14386fa3b

Liked it? Take a second to support Mte90 on Patreon!
Become a patron at Patreon!

Leave a Reply

Your email address will not be published. Required fields are marked *