In a previous article we explained the simple steps you can take to secure your WordPress website. With the same topic in mind, we’re going to look at another aspect of WordPress websites, nonces, what they are and how the can affect your site from a security perspective.
Let’s get going!
What are Nonces?
A nonce by definition is something that is used only once and without recurrence.
In a WordPress website, nonces are used to validate the contents of a form and avoid malicious activity. More specifically, a nonce protects your website from Cross-Site Request Forgeries (CSRFs) attacks. It is not considered a guaranteed protection, but suffices in most cases.
They are hashes that are made up of numbers and letters. They are used only once and have a limited lifetime cycle which means that after a certain amount of time has passed they will expire. During its lifecycle, the nonce will remain the same and will be related to a specific user and context.
How Nonces Protect a Website
When a user submit a form, for example, a CSRF attack can force the user to execute unwanted actions. Depending on the access level of the user involved, the damage can range from an email address being changed right through to the entire site being compromised.
To avoid this, a nonce is added in the corresponding submit URL to be checked and only then allow the action to complete if that value is correct and not expired.
A common example of nonce use in WordPress is when deleting a post.
If WordPress did not use nonces, the Trash link would generate a URL like this:
https://mycompanyname.com/wp-admin/post.php?post=98&action=trash
In this case, the attacker could potentially leverage this unsecured link causing you to unwittingly delete your own posts when you didn’t want to. This is called a Cross-Site attack.
Try our Award-Winning WordPress Hosting today!
Adding a nonce would prevent this. In the above scenario, the use of a nonce would lead to a “403 Forbidden” response with an ‘Are you sure you want to do this?’ message because the hacker’s URL would lack this extra verification.
The URL that WordPress normally generates when you are about to delete a post looks something like this:
https://mycompanyname.com/wp-admin/post.php?post=98&action=trash&_wpnonce=b05b7aedf8
The _wpnonce=b05b7aedf8
is what secures the url and ensures that only you are able to carry out tasks like deleting posts on your site.
Nonces and WordPress
When managing a WordPress website, nonces are generated by WordPress itself in order to protect your URLs and forms from being misused. So, unless you are developing themes or plugins it’s unlikley you’ll ever need to worry about nonces as everything is taken care of by WordPress.
When building a theme or plugin as a developer though, you should handle the nonces yourself by using the functions that WordPress provides for that purpose.
To create a Nonce, you can use the wp_nonce_url() to add a nonce to an URL, the wp_nonce_field() to add a nonce to a form or the wp_create_nonce() if you wish to use a nonce in a custom way, like in an AJAX request.
When it comes to verifying nonces, you can use the check_admin_referer() to verify a nonce that was passed in a URL or a form in an admin screen, the check_ajax_referer() that checks the nonce and if it fails then by default terminates script execution and the wp_verify_nonce() to verify a nonce passed in some other context.
Create the Nonce
As a quick example we will add a submit action in the Settings Page of a custom plugin.
Let’s say that you are building a submit button in your plugin’s Settings Page that is designed to clear some Log files. In the code you should keep the final nonced URL in a variable to be used later in the form code:
$nonce_url = wp_nonce_url( $url, 'clear-logs' );
The wp_nonce_url
function that is used here is structured like this:
wp_nonce_url( $actionurl, $action, $name )
In this example, $actionurl
is, as expected, the required URL (string). It is this URL to which you will apply the nonce. The $action
parameter is an optional nonce action name (int|string
) and $name
is an optional Nonce name (string) with the default value ‘_wpnonce’. We should point out here that, as described above, it is not mandatory to use an action unique name. It is however wise that you do so because that way your nonce can’t be reused to verify another type of request and will be even more secure.
So if the $url you use in your code for clearing logs is something like:
https://mycompanyname.com/logs.php?clear=yes
then with the use of nonce it will become:
https://mycompanyname.com/logs.php?clear=yes&_wpnonce=b05b7aedf8
NOTE: The default lifetime of a nonce is 24 hours.
Verify the Nonce
On submission, you will have to check the validity of the request. The wp_verify_nonce
function that we will use returns an escaped URL with nonce action added and is structured like this:
wp_verify_nonce( $nonce, $action )
In the $nonce
required parameter we give the Nonce value that was used for verification and the $action
parameter should be the same with $action in wp_nonce_url()
.
The piece of code that will perform the check could be as follows:
if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'clear-logs' ) ) {
// Actions to do should the nonce is invalid
}
Conclusion
Cross Site Request Forgery (CSRF) is a well known vulnerability in WordPress world and therefore it is important to be pro-active in protecting against it. Nonces are vital in helping prevent a CSRF attack and should always be used where required.
Start Your 14 Day Free Trial
Try our award winning WordPress Hosting!