Nonce Verification

What is Nonce Verification in WordPress?

Nonce verification in WordPress is a security method that checks if a request made to the site is valid and comes from an authorized source. It helps block malicious actions like Cross-Site Request Forgery (CSRF), where someone tries to perform actions on behalf of a logged-in user without permission.

Purpose of Nonce Verification

WordPress uses nonces to confirm that the person performing an action has the right to do so. When combined with a permission check, this helps stop unauthorized changes. For example, when a user deletes a post or changes settings, WordPress verifies that the request comes from a valid session and not from an external source.

Without nonce verification, attackers could create links or forms that cause users to take unwanted actions, such as deleting data or changing account settings.

How WordPress Generates Nonces

WordPress creates nonces using wp_create_nonce(). This function builds a hash using the current user’s ID, authentication token, timestamp (called a “tick”), and a defined action string. The result is a unique token tied to that specific action and user.

The information used in this generation process includes the session token (tied to a logged-in session) and other secret keys from the WordPress setup. Each nonce is tied to a specific action and user session.

Nonce Expiration and Ticks

WordPress nonces are valid for up to 24 hours. Internally, WordPress divides each day into two 12-hour blocks called “ticks.” If a nonce is created during one tick, it will stay valid through that tick and the next one, offering a window of slightly more than 12 hours and up to 24 hours in total.

Once the nonce falls outside this tick range, it will fail verification. The function wp_verify_nonce() returns the tick number (1 or 2) if the nonce is valid and false if it is not.

Adding Nonces to URLs and Forms

To attach a nonce to a link or form, WordPress provides helper functions:

  • wp_nonce_url($url, $action) adds a nonce to a URL for a specific action.
  • wp_nonce_field($action, $name) adds a hidden input field to a form containing the nonce.

Example for URL:

php
$delete_url = wp_nonce_url('admin.php?page=delete&user=5', 'delete-user_5');

Example for form:

php
wp_nonce_field('delete-user_5', '_wpnonce', false);

This ensures any site interaction—URL click or form submit—carries the correct nonce.

Verifying Nonces

Nonce verification uses different functions based on the context:

wp_verify_nonce() checks a nonce manually and returns the tick number or false.

php
if (!wp_verify_nonce($_POST['_wpnonce'], 'delete-user_5')) {
wp_die('Failed verification');
}

Check_admin_referer() verifies nonce input from admin forms.

php
check_admin_referer('delete-comment_10');

Check_ajax_referer() verifies nonces sent with AJAX calls.

php
check_ajax_referer('custom-action_45', '_ajax_nonce');

If these checks fail, WordPress stops the request and returns a 403 Forbidden response.

Common Use Cases

Nonce verification is used across WordPress core features:

When a user trashes a post:

php
http://example.com/wp-admin/post.php?post=23&action=trash&_wpnonce=b1a2d3ef90

If the nonce is invalid or missing, WordPress blocks the action.

When deleting a comment from the admin panel:

php
http://example.com/wp-admin/comment.php?c=211&action=deletecomment&_wpnonce=6ad8bcf18e

In both cases, the server verifies the nonce before processing the request. If the check fails, the operation ends with an error.

Dependence on User Session

A nonce is only valid when tied to a valid session. If a user logs out, all their nonces become invalid. Even if someone else has the nonce, they can’t use it without a matching session.

This reduces the risk of replay attacks, where an attacker tries to reuse a valid request. The nonce check ensures both the token and session are active.

Working with Permissions

A nonce only validates the request origin. It doesn’t check user permissions. To confirm a user is allowed to perform an action, combine nonce checks with current_user_can().

Example:

php
if (
!current_user_can('delete_posts') ||
!wp_verify_nonce($_POST['_wpnonce'], 'delete-post_123')
) {
wp_die('Unauthorized request');
}

This adds an extra layer of security beyond nonce validation.

Troubleshooting Verification Failures

When nonce verification fails, users often see an error like “Are you sure you want to do this?” or a 403 error. This usually means:

  • The nonce expired
  • It was missing from the request
  • A plugin or theme generated it incorrectly

To fix these issues:

  • Clear browser cache
  • Log back in to refresh the session
  • Disable plugins to identify the source of the fault
  • Check if AJAX requests include both the nonce and expected action

Developer Hooks for Nonce Behavior

WordPress includes hooks to control or monitor nonce handling:

  • nonce_user_logged_out adjusts how nonces are handled for logged-out users.
  • wp_verify_nonce_failed runs when nonce verification fails. Developers can use this to log security events or adjust behavior.

These hooks allow developers to add custom behavior tied to nonce outcomes or manage session rules.

Leave a Comment

Your email address will not be published. Required fields are marked *

Share via
Copy link