Tutorials UPDATED: 30 June 2024

Understanding WordPress Nonces: Enhance Site Security Effectively

Tassos Antoniou

6 min read

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!

OUR READERS ALSO VIEWED:

See how Pressidium can help you scale
your business with ease.