This is a follow up article for the creating a WordPress plugin tutorial
Nonce – what is it and why is it important when it comes to WordPress and security?
What Does Nonce Mean?
The word “nonce” is an abbreviation for the term number used once and is a string generated by WordPress which acts as a special token and is used to identify the person doing a specific operation such as the submission of a form, deletion of a post etc.
Why Use Nonce?
The nonce’s main purpose is to protect against malicious hacking attacks such as a technique known as Cross Site Request Forgery (CSRF) which involves tricking people into clicking a link which will cause harm to your site.
Another way to describe a nonce is that it is sort of like a temporary secret key or fingerprint which is unique only to you and can only ever be used by you for a specific operation and it is extremely difficult to be guessed by somebody else.
How Does It Work?
The nonce value is valid for 24 hours after which it expires and a new one will be generated.
This ensures that someone cannot copy an old nonce and re-inject it into the URL of an operation or HTTP request.
Nonces are widely used in the core functionality of WordPress but you may not have been specifically aware of them. For example, let’s say you are an administrator of a WordPress blog and you want to delete a specific user account.
When you click on the “delete†link, WordPress will generate a nonce and it will add it in the URL as follows:
http://www.yoursite.com/wp-admin/users.php?action=delete&user=5&_wpnonce=94f3a1e666
The above nonce will be valid for 24 hours and it can only be used by you and only for this specific operation – which in this case is the deletion of the user with the id value of “5â€.
Now let’s say that moments after successfully deleting the user you also wanted to delete a post. When you click on the “trash†link for that post, WordPress will once again generate a new nonce value specifically for this operation:
http://www.yoursite.com/wp-admin/post.php?post=1&action=trash&_wpnonce=3a6dc727ba
Note how the value of this nonce is different to the first one and again the same rule applies here in that it will only be valid for 24 hours and can only be used for the deletion (trash action) of the post with id value of 1.
Thus when a user clicks a link in the admin panel such as the delete or trash links in the examples above, WordPress will do some checks behind the scenes to verify that the “_wpnonce†parameter is valid and if and only if it is valid, it will proceed with the completion of the request.
If the value for “_wpnonce” was found to be invalid then WordPress will not allow the operation and the user would be greeted with a screen that tells them the error.
Plugin Developers
If you are a WordPress plugin developer or have aspirations to become one, then you should learn and embrace the concept of nonces and apply them to your code where applicable.
WordPress has several useful functions available to you which you can use for all matters related to nonces.
Creating nonces
There are functions to create and add nonces to your URLs and forms in WordPress.
Adding a nonce to a URL
For example, WordPress has the following function which will create a nonce which you can manually add to your URL:
wp_create_nonce($action)
This function will create a nonce value and as you can see it takes a single argument, which is a string defining the action you are performing.
The string can be anything you wish and it is advisable that you choose something unique to your plugin which will be hard to guess.
The function will return a string in the form of the nonce token value.
Example 1:
For example let’s assume you have written a plugin which has a page with a list of items with a delete link next to each item. To further enhance security you want to add a nonce to the delete link.
The following is one way you could do it using the function above:
1) First you would create the nonce:
$my_nonce = wp_create_nonce('delete_my_rec');
2) Next you would add this nonce to your URL:
<a href='admin.php?page=mypluginpage&action=delete&recid=1&_wpnonce=<?php echo $my_nonce ?>'>Delete Me</a>
An alternative way to add a nonce to a URL is to use the following function:
wp_nonce_url($actionurl, $action)
This function takes two parameters.
- The first is the URL you wish to add the nonce to
- The second is the action name you wish to assign to the nonce.
If you look inside the WordPress core code you will see that wp_nonce_url function actually calls the wp_create_nonce function to create the nonce which it then adds to the URL string.
Example 2:
Therefore, we can use the wp_nonce_url function to achieve the same outcome as in the first example by simply doing the following:
1) Create the URL with a nonce added to it:
$nonced_url = wp_nonce_url('admin.php?page=mypluginpage&action=delete&recid=1', 'delete_my_rec');
2) Now add the URL containing the nonce to our page:
echo '<a href="'.$nonced_url.'">Delete Me</a>';
This second example will achieve the same outcome as the first example.
Adding a nonce to a form
To add a nonce to a form you can use the following function:
wp_nonce_field($action, $name, $referer, $echo)
This function takes 4 parameters all of which are optional:
- $action = (optional) this is a string which represents the action name
- $name = (optional) this is a string which represents the name of the nonce. If you leave this field blank WordPress will default to “_wpnonceâ€
- $referer = (optional) this is a Boolean. It determines whether the referrer “hidden form field†should be created. This is basically the “REQUEST_URI†value of the referring page which is stored in the PHP superglobal $_SERVER. If not included it defaults to true.
- $echo =Â (optional) this is a Boolean. It determines whether WordPress should echo the nonce hidden field or return its value. If not included it defaults to true (which means it will echo the field)
This function will return a URL string which will contain the nonce action.
Example 3:
A typical usage for this function is shown in example below:
<form action="" method="post"> <?php wp_nonce_field('my_delete_action'); ?> <input type="hidden" name="id" value=" <?php echo $id; ?> " /> <input type="text" name="rec_name" value=" <?php echo $name; ?> " /> <input type="submit" value="Delete" /> </form>
Note how we’ve inserted our hidden nonce field inside the form by using the wp_nonce_field function and we’ve included a single parameter “my_delete_action†which represents action name of our nonce.
Verifying nonces
Creating and inserting nonces in our code is only half of the work that needs to be done.
We need to also verify the nonces when the user tries to submit a form or performs an action via a URL.
To verify a nonce we can simply use the following WP function:
wp_verify_nonce($nonce, $action)
This function takes 2 parameters:
- $nonce = (required) this is the particular nonce you want to verify
- $action = (optional) this is the action you specified for the nonce when you created it.
The above function will return a Boolean “false†if the nonce was invalid; otherwise it will return an integer based on when the nonce was generated, ie,
It will return “1†if nonce was generated 12hours or less
It will return “2†if nonce was generated greater than 12 hours and less than 24 hours ago.
Example 4:
Therefore using our nonce we created in example 1 we can now expand our code to include the following check:
$retrieved_nonce = $_REQUEST['_wpnonce']; if (!wp_verify_nonce($retrieved_nonce, 'delete_my_rec' ) ) die( 'Failed security check' );
An alternative way to verify nonces
You can also use the following function to verify your nonce:
check_admin_referer($action, $query_arg)
Where:
- $action = (optional) is the action name. It is highly recommended to include this field when calling this function.
- $query_arg = (optional) denotes the nonce name which WordPress will look for in the $_REQUEST variable. (defaults to _wpnonce if left blank)
If the nonce is valid the function lets your plugin’s execution proceed otherwise it will “die†and take the user to the “are you sure†error page if it determines that a nonce is invalid.
Example 5:
Therefore we could use the line of code below to replace the code of example 4 to achieve a similar result:
check_admin_referer('delete_my_rec');
We’ve briefly touched the subject of nonces in this article which should give you enough info to start using them in your code (where applicable). Feel free to post a comment if you have any question on this subject.
Thanks for writing this! Saved me a ton of time by aggregating all the nonce functions and providing links to codex!
Great and useful post!
I would like to bring some perspective on the nonce lifetime. A nonce is not valid for 24 hours, but rather for a maximum of 24 hours.
A nonce will be regenerated every 12 hours. Which is the minimum lifespan of a nonce.
To avoid confusion, we should talk about ticks instead of hours, since a nonce is valid for 2 ticks. A tick is incremented every 12 hours ( UTC ), which is the default value, but it could be changed to be shorter or longer.
I have written an extensive post about nonces, explaining this in details. It can be found here: https://www.bynicolas.com/code/wordpress-nonce/
Thanks for sharing and keep up the good work !
@Roy, thank you.
Another things that we should check if form submit to use “check_admin_referer”
Like
if(isset($_POST[‘submit’])){
if(check_admin_referer(‘optionName’)){
Ok!
}
}
Nice explanetion! there is a typo “check_admin_referrer” should be “check_admin_referer”
Regards
Awesome Article. its very helpful. Great job