DefinitionsWordPressWhat is WordPress Nonces?
WordPress

What is WordPress Nonces?

WordPress nonces are single-use security tokens that protect against cross-site request forgery (CSRF) attacks by verifying that a request originated from a legitimate user action within the WordPress admin interface.

WPSentry TeamMarch 9, 20265 min read
Table of Contents 5 sections

What Are WordPress Nonces?

WordPress nonces (short for "number used once") are cryptographic security tokens used to verify that a request to perform an action was intentionally made by an authenticated user and not forged by a malicious third party. Despite the name, WordPress nonces are not strictly single-use; they are time-limited tokens that remain valid for a configurable period (24 hours by default, split into two 12-hour ticks). Nonces are the primary WordPress mechanism for preventing cross-site request forgery (CSRF) attacks, where an attacker tricks a user's browser into performing unwanted actions on a site where the user is authenticated.

A WordPress nonce is a hash generated from a combination of the nonce action string, the current user's session token, the user's ID, and a time-dependent tick value. This means each nonce is unique to a specific action, a specific user, and a specific time window. Even if an attacker intercepts a nonce, it cannot be reused for a different action, a different user, or outside its validity window. The nonce system is deeply integrated into WordPress core and is used to protect virtually every administrative action, from publishing posts to installing plugins to changing settings.

How WordPress Nonces Work

The nonce lifecycle involves three steps: generation, inclusion, and verification. A nonce is generated using wp_create_nonce('action_name'), which produces a hash string tied to the specified action and the current user. This nonce is then included in a form as a hidden field using wp_nonce_field('action_name'), appended to a URL using wp_nonce_url(), or passed as a parameter in an AJAX request. When the form is submitted or the URL is accessed, WordPress retrieves the nonce and verifies it against the expected action.

Verification is performed using wp_verify_nonce($nonce, 'action_name') for general use or check_admin_referer('action_name') for admin form submissions. If the nonce is valid and was generated within the current or previous tick, verification succeeds and the action proceeds. If the nonce is missing, invalid, or expired, WordPress rejects the request. For AJAX handlers, check_ajax_referer('action_name') provides equivalent protection. These verification functions should be called at the very beginning of any request handler before any processing occurs.

Nonces and CSRF Protection

Cross-site request forgery is an attack where a malicious website, email, or script causes an authenticated user's browser to perform an unwanted action on a target site. For example, an attacker could embed an image tag or form on a malicious page that makes a request to example.com/wp-admin/options.php to change the site's admin email address. Without nonce protection, the browser would include the user's authentication cookies with the request, and WordPress would process it as a legitimate administrative action.

Nonces prevent CSRF because the attacker cannot generate a valid nonce for the target action. The nonce depends on the user's session token, which is stored in an HTTP-only cookie that JavaScript on a third-party site cannot access. Even if the attacker knows the action name and all other parameters, they cannot forge the nonce without access to the user's session. This makes nonces an essential security layer for any WordPress operation that changes state, from publishing a post to deleting a user to modifying plugin settings.

Common Nonce Implementation Mistakes

One of the most frequent mistakes developers make is omitting nonce verification entirely. Many plugin and theme developers include nonces in their forms but forget to verify them in the handler, rendering the protection useless. Another common error is using generic or predictable action names like wp_create_nonce('nonce') or wp_create_nonce('my-action') instead of specific, descriptive action names tied to the exact operation being protected. While this does not completely negate security (the nonce still depends on the user session), specific action names prevent nonce reuse across different operations.

Developers also sometimes expose nonces unnecessarily by including them in cached pages, GET parameters visible in server logs, or JavaScript variables accessible to untrusted code. While nonces are user-specific and time-limited, unnecessary exposure increases the risk of exploitation. Another subtle mistake is verifying nonces but not checking user capabilities. Nonce verification confirms that the request was intentional, but it does not confirm that the user has permission to perform the action. Both wp_verify_nonce() and current_user_can() must be used together for complete protection.

Nonce Security Best Practices

Every form submission, AJAX request, and URL-based action in a WordPress plugin or theme should be protected by a nonce. The nonce action name should be specific and descriptive, incorporating the operation type and the target resource where possible (for example, 'delete_post_' . $post_id). Nonce verification should occur before any other processing in the request handler, and the handler should immediately terminate with an appropriate error if verification fails. Using wp_die() or returning a WP_Error object provides clear feedback when a nonce check fails.

For AJAX operations, nonces should be localised to the page using wp_localize_script() or wp_add_inline_script() and passed with each AJAX request. The handler should use check_ajax_referer() to verify the nonce. Developers should never extend the nonce lifetime beyond the default 24 hours unless there is a compelling reason, as longer validity windows increase the risk of token reuse. For particularly sensitive operations like account deletion or financial transactions, requiring fresh authentication in addition to nonce verification provides an additional layer of assurance that the request is legitimate.

FAQ

Frequently Asked Questions

No. Despite the name, WordPress nonces are time-limited tokens valid for 24 hours (two 12-hour ticks), not strictly single-use. They are tied to a specific action, user, and time window to prevent cross-site request forgery.

If nonce verification fails, the request should be rejected immediately. WordPress typically displays a 'Are you sure you want to do this?' message or returns a 403 Forbidden error, preventing the action from being executed.

For cookie-based authentication in the REST API, WordPress automatically includes a nonce via the X-WP-Nonce header. For application password or token-based authentication, nonces are not required as the authentication mechanism itself validates the request origin.

Tags

Related Definitions