Verifies that a correct security nonce was used with time limit.
Description
A nonce is valid for 24 hours (by default).
Parameters
$nonce
stringrequired- Nonce value that was used for verification, usually via a form field.
$action
string|intoptional- Should give context to what is taking place and be the same when nonce was created.
Default:
-1
Source
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|int $action The nonce action, or -1 if none was provided.
*/
$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
}
if ( empty( $nonce ) ) {
return false;
}
$token = wp_get_session_token();
$i = wp_nonce_tick( $action );
// 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;
}
Hooks
- apply_filters( ‘nonce_user_logged_out’,
int $uid ,string|int $action ) Filters whether the user who generated the nonce is logged out.
- do_action( ‘wp_verify_nonce_failed’,
string $nonce ,string|int $action ,WP_User $user ,string $token ) Fires when nonce verification fails.
Changelog
Version | Description |
---|---|
2.0.3 | Introduced. |
Example
Verify an nonce created with
wp_create_nonce()
:You may also decide to take different actions based on the age of the nonce:
Per the WordPress Coding Standards, this is the way as to verify a nonce:
This system is not very accurate and the comment about the return values is incorrect. The value
1
means < 12 hours old, but2
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.