WordPress Nonce

What Is a Nonce?

Nonce stands for “number used once“. Despite this name WordPress nonces aren’t strictly numbers and they’re not used only once. Instead, a WordPress nonce is a hash made up of numbers and letters and it has a limited lifetime (one day by default).

Why You Need a Nonce

Nonces are used to prevent Cross Site Request Forgery or CSRF attacks. These attacks are done when malicious code on a sketchy website makes your browser send a GET or POST request to another website on which you’re already logged in. If you’re logged in to the target website, your browser will automatically include the authentication cookies with the request so the target website may assume you actually wanna perform an action. Check this short YouTube video or this long one to learn more about CSRF.

When you’re in WordPress backend on the posts, if you hover on the trash button for a post you’ll see the link is something like this

https://your-site.com/wp-admin/post.php?post=123&action=trash&_wpnonce=b192fc4204

So when you click on the trash button, WordPress first checks the nonce and if it’s valid trashes the post. Now imagine there was no nonce and the trash link was like

https://your-site.com/wp-admin/post.php?post=123&action=trash

In this case a malicious person could hide this link on their website and get you to click on it. Something like this

Or even hide the link in an image on their site, like this

<img src=”http://example.com/wp-admin/post.php?post=123&action=trash” />

In this case you don’t even need to click anywhere. As soon as you go to the attacker’s site your browser will try to load this image and as a result will send a GET request to that URL. Because browsers automatically send cookies to the associated domains, when your browser is sending the GET request to your website, it’ll also send the WordPress authentication cookie stored in it (assuming you’ve recently logged in to your site).

So if WordPress didn’t have nonces and only relied on the authentication cookies, it’d trash the posts on your site without you even being on your site.

When You Need a Nonce

Nonces are most useful when the user can perform an important or irreversible action by clicking on a link or submitting a form (in other words a GET or POST request). Something like a delete post or remove account button or changing the email of the account. Nonces are not required or useful for insignificant functionalities like viewing a post or logging out.

Out of the box WordPress implements nonces on all default functionalities that need to be secure (like removing posts, users, ….) but if you’re adding custom functionality in your theme or plugin, you probably need to implement nonces.

How to Create a Nonce

There are three ways to create a nonce in WordPress. One specifically to add a nonce to a URL, another one to add a nonce to a form and the last one to create a nonce for any other use cases. These functions are:

  • wp_nonce_url() to add a nonce to a URL
  • wp_nonce_field() to add a hidden nonce field to a form
  • wp_create_nonce() to create a nonce for any other purposes

How to Verify a Nonce

Adding a nonce to a URL or form by itself doesn’t add any security. We need to verify the nonce before doing anything with the request. There are three functions to verify a nonce depending on the context:

  • check_admin_referer() to verify a URL or form nonce in an admin screen
  • check_ajax_referer() to verify a nonce passed in an AJAX request
  • wp_verify_nonce() to verify a nonce passed in some other context