Demystifying Nonces in WordPress

Hey there! Let‘s take a deep dive into nonces in WordPress. I‘ll explain what they are, how they work, and why they‘re so important for securing your site. Grab a coffee and let‘s geek out!

What is a Nonce?

A nonce is a "number used once" or a cryptographically random one-time key used for verification.

WordPress generates a unique nonce value whenever it needs to verify the authenticity of a request. This nonce gets included in the request parameters.

For example, when deleting a comment, the URL might look like:

http://example.com/wp-admin/comment.php?c=123&action=deletecomment&_wpnonce=8ag7c9ae85

That _wpnonce=8ag7c9ae85 value is the nonce for this action.

When the request comes back, WordPress compares the submitted nonce to the expected value. If it matches, the request proceeds. If not, it fails with the infamous "Are you sure you want to do this?" error we‘ve all seen.

This prevents cross-site request forgery and other attacks by verifying each request is authorized.

Where You‘ll Find Nonces in WordPress

Here are some examples of WordPress using nonces to protect forms, URLs, AJAX calls, and more:

Query Strings in Admin URLs

Any admin URL that performs an action like editing a post, deleting a comment, etc. will use a nonce. For example:

http://example.com/wp-admin/edit.php?post_type=page&post=123&action=edit&_wpnonce=e23f8b9c05

Hidden Fields in Forms

The wp_nonce_field() function adds a hidden nonce field to forms. When submitting the form, this nonce is validated:

<input type="hidden" name="_wpnonce" value="d7e3f9a715">

AJAX Requests

For AJAX calls, WordPress handles automatically passing nonces in the request headers when using wp_ajax_* actions or wp_localize_script().

Uploading Files

Uploading files via the media library or author forms requires a valid nonce in the request. This prevents unauthorized uploads to your site.

REST API Endpoints

Nonces help lock down REST API endpoints as well. The wp_rest_nonce_url() function handles generating nonced URLs.

As you can see, nonces pop up all over the place in WordPress!

How Does WordPress Verify Nonces?

When a request contains a nonce, here is what happens during verification:

  1. WordPress checks the nonce against the $nonces array populated during that page load.

  2. The nonce salts and keys from wp-config.php are used to determine if the nonce is valid and authorized.

  3. If the nonce is valid, the request proceeds. If not, it fails with the "Are you sure you want to do this?" error.

  4. As an additional security check, nonces expire after 12-24 hours by default even if valid.

By tying the nonce to a specific user session and page load, this prevents the nonce from being re-used across requests. The nonce salts and keys in wp-config.php provide entropy for generating unique nonce values.

According to WordPress developer Mark Jaquith, approximately 1.7 billion nonce values are checked during each minor release cycle!

Troubleshooting Nonce Issues

Sometimes you might run into an "Are you sure you want to do this?" nonce error unexpectedly. Here are some tips on debugging:

  • Disable plugins – Often a plugin conflict causes nonce issues. Disable plugins one-by-one to isolate.

  • Switch themes – The problem could be caused by your custom theme‘s nonce implementation.

  • Review code changes – Check for any modifications that may have removed nonce verification.

  • Increase nonce lifespan – For complex workflows, you may need to increase the nonce expiry time.

  • Check request headers – Inspect the HTTP requests using developer tools to verify nonces.

  • Log nonces – Adding some logging can help diagnose where invalid nonces originate.

With a bit of testing, you can typically uncover what is causing the invalid or expired nonces.

Best Practices for Nonces

When building plugins and themes, be sure to properly validate any nonce fields, REST API calls, uploads, etc. Some tips:

  • Always use wp_verify_nonce() to verify nonces.

  • Generate nonces using wp_create_nonce() as needed.

  • For forms, use wp_nonce_field() to add the hidden field.

  • Follow WordPress coding standards for nonce implementation.

  • If extending timeout, do so judiciously to avoid replay attacks.

Following these best practices will keep your customizations secure.

Wrap Up

I hope this guides gives you a good overview of how nonces work in WordPress and why they‘re so important for security!

Let me know if you have any other questions. Happy coding!

Written by Jason Striegel

C/C++, Java, Python, Linux developer for 18 years, A-Tech enthusiast love to share some useful tech hacks.