wp_verify_nonce( string $nonce, string|int $action = -1 )

Verifies that a correct security nonce was used with time limit.


Description Description

A nonce is valid for 24 hours (by default).


Top ↑

Parameters Parameters

$nonce

(string) (Required) Nonce value that was used for verification, usually via a form field.

$action

(string|int) (Optional) Should give context to what is taking place and be the same when nonce was created.

Default value: -1


Top ↑

Return Return

(int|false) 1 if the nonce is valid and generated between 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago. False if the nonce is invalid.


Top ↑

More Information More Information

The function is used to verify the nonce sent in the current request usually accessed by the $_REQUEST PHP variable.

Nonces should never be relied on for authentication or authorization, access control. Protect your functions using current_user_can(), always assume Nonces can be compromised.


Top ↑

Source Source

File: wp-includes/pluggable.php

	function wp_verify_nonce( $nonce, $action = -1 ) {
		$nonce = (string) $nonce;
		$user  = wp_get_current_user();
		$uid   = (int) $user->ID;
		if ( ! $uid ) {
			/**
			 * Filters whether the user who generated the nonce is logged out.
			 *
			 * @since 3.5.0
			 *
			 * @param int    $uid    ID of the nonce-owning user.
			 * @param string $action The nonce action.
			 */
			$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
		}

		if ( empty( $nonce ) ) {
			return false;
		}

		$token = wp_get_session_token();
		$i     = wp_nonce_tick();

		// Nonce generated 0-12 hours ago.
		$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
		if ( hash_equals( $expected, $nonce ) ) {
			return 1;
		}

		// Nonce generated 12-24 hours ago.
		$expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
		if ( hash_equals( $expected, $nonce ) ) {
			return 2;
		}

		/**
		 * Fires when nonce verification fails.
		 *
		 * @since 4.4.0
		 *
		 * @param string     $nonce  The invalid nonce.
		 * @param string|int $action The nonce action.
		 * @param WP_User    $user   The current user object.
		 * @param string     $token  The user's session token.
		 */
		do_action( 'wp_verify_nonce_failed', $nonce, $action, $user, $token );

		// Invalid nonce.
		return false;
	}


Top ↑

Changelog Changelog

Changelog
Version Description
2.0.3 Introduced.

Top ↑

User Contributed Notes User Contributed Notes

  1. Skip to note 1 content
    Contributed by Codex

    Example
    Verify an nonce created with wp_create_nonce():

    <?php
    // Step A: Create an nonce, and add it as a query var in a link to perform an action.
    $nonce = wp_create_nonce( 'my-nonce' );
    echo "<a href='myplugin.php?_wpnonce={$nonce}'>" . __( 'Save Something', 'textdomain' ) . "</a>";
    ?>
    
    // Step B: In our file that handles the request, verify the nonce.
    $nonce = $_REQUEST['_wpnonce'];
    if ( ! wp_verify_nonce( $nonce, 'my-nonce' ) ) {
    	die( __( 'Security check', 'textdomain' ) ); 
    } else {
    	// Do stuff here.
    }
    

    You may also decide to take different actions based on the age of the nonce:

    $nonce = wp_verify_nonce( $nonce, 'my-nonce' );
    switch ( $nonce ) {
    	case 1:
    		echo 'Nonce is less than 12 hours old';
    		break;
    	case 2:
    		echo 'Nonce is between 12 and 24 hours old';
    		break;
    	default:
    		exit( 'Nonce is invalid' );
    }
    
  2. Skip to note 3 content
    Contributed by Roy

    This system is not very accurate and the comment about the return values is incorrect. The value 1 means < 12 hours old, but 2 means anywhere from 1 second to < 24 hours old.

    Observe what happens to the nonce tick value over a day:

    local time ~~~ seconds since epoch ~~~ tick
    2021-05-20T00:00:00+03:00 ~~~ 1621458000 ~~~ 37534
    2021-05-20T01:00:00+03:00 ~~~ 1621461600 ~~~ 37534
    2021-05-20T02:00:00+03:00 ~~~ 1621465200 ~~~ 37534
    2021-05-20T03:00:00+03:00 ~~~ 1621468800 ~~~ 37534
    2021-05-20T04:00:00+03:00 ~~~ 1621472400 ~~~ 37535
    2021-05-20T05:00:00+03:00 ~~~ 1621476000 ~~~ 37535
    2021-05-20T06:00:00+03:00 ~~~ 1621479600 ~~~ 37535
    2021-05-20T07:00:00+03:00 ~~~ 1621483200 ~~~ 37535
    2021-05-20T08:00:00+03:00 ~~~ 1621486800 ~~~ 37535
    2021-05-20T09:00:00+03:00 ~~~ 1621490400 ~~~ 37535
    2021-05-20T10:00:00+03:00 ~~~ 1621494000 ~~~ 37535
    2021-05-20T11:00:00+03:00 ~~~ 1621497600 ~~~ 37535
    2021-05-20T12:00:00+03:00 ~~~ 1621501200 ~~~ 37535
    2021-05-20T13:00:00+03:00 ~~~ 1621504800 ~~~ 37535
    2021-05-20T14:00:00+03:00 ~~~ 1621508400 ~~~ 37535
    2021-05-20T15:00:00+03:00 ~~~ 1621512000 ~~~ 37535
    2021-05-20T16:00:00+03:00 ~~~ 1621515600 ~~~ 37536
    2021-05-20T17:00:00+03:00 ~~~ 1621519200 ~~~ 37536
    2021-05-20T18:00:00+03:00 ~~~ 1621522800 ~~~ 37536
    2021-05-20T19:00:00+03:00 ~~~ 1621526400 ~~~ 37536
    2021-05-20T20:00:00+03:00 ~~~ 1621530000 ~~~ 37536
    2021-05-20T21:00:00+03:00 ~~~ 1621533600 ~~~ 37536
    2021-05-20T22:00:00+03:00 ~~~ 1621537200 ~~~ 37536
    2021-05-20T23:00:00+03:00 ~~~ 1621540800 ~~~ 37536

    …and over the boundary of a tick:

    local time ~~~ seconds since epoch ~~~ tick
    2021-05-20T14:59:58+03:00 ~~~ 1621511998 ~~~ 37535
    2021-05-20T14:59:59+03:00 ~~~ 1621511999 ~~~ 37535
    2021-05-20T15:00:00+03:00 ~~~ 1621512000 ~~~ 37535
    2021-05-20T15:00:01+03:00 ~~~ 1621512001 ~~~ 37536
    2021-05-20T15:00:02+03:00 ~~~ 1621512002 ~~~ 37536

    In this example, you can see that a nonce generated at 3pm and verified one second later will return 2 because of the tick change. The ticks do not align with timezones due to their basis in universal time, so nonces will always appear “old” to your code at certain times of the day.

You must log in before being able to contribute a note or feedback.