How to expire a nonce?

The problem with expiring a nonce is that in WordPress, nonces aren’t nonces in the purest sense of the term: “number used once.” Rather, a WP nonce is a (substring of a) hash of a string involving a time signature at the moment it was generated, among other things: user ID, the action name and your php session token. As such, once generated, it is what it is, it’s “use-by” date is baked in, and you can’t expire it (and you can’t extend it).

Edit:

You can see how the nonce is built in wp-includes/pluggable.php:

function wp_create_nonce($action = -1) {
    $user = wp_get_current_user();
    $uid = (int) $user->ID;
    if ( ! $uid ) {
        /** This filter is documented in wp-includes/pluggable.php */
        $uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
    }

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

    return substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );

The same set of criteria are used in wp_verify_nonce(): nonce_tick (which is the time element), action, token and uid are all combined and hashed in the same order and compared to the submitted nonce. So, if any of these have changed, the hashes will not match and the nonce is rejected.

End Edit

WP validates it only by whether a submitted string time-matches (via php’s hash_equals()) an expected value that is generated when you pass in the nonce string along with the action. If the nonce and action combine with your current user ID and session token to create a hash substring that matches the time-hash check, you pass.

What’s missing to make a WP nonce a “true” nonce is a check to see if it has already been used/processed once before.

The security assumption is that it doesn’t matter, because even if someone gets ahold of the nonce and its corresponding action, you would still need to submit it using the same User ID and php session token under which it was generated — highly unlikely unless a hacker has hijacked your device and is logged in as you… but by then you have a different kind of security problem.

Leave a Comment