WordPress.org

Make WordPress Core

Opened 8 weeks ago

Closed 8 weeks ago

Last modified 8 weeks ago

#41993 closed enhancement (invalid)

wp_nonce_tick() - is division on 2 it a real need?

Reported by: Tkama Owned by:
Milestone: Priority: normal
Severity: normal Version: 2.5
Component: General Keywords:
Focuses: Cc:

Description

Let's look into code

function wp_nonce_tick() {
        /**
         * Filters the lifespan of nonces in seconds.
         *
         * @since 2.5.0
         *
         * @param int $lifespan Lifespan of nonces in seconds. Default 86,400 seconds, or one day.
         */
        $nonce_life = apply_filters( 'nonce_life', DAY_IN_SECONDS );

        return ceil(time() / ( $nonce_life / 2 ));
}

It seams right to do division in filter value - DAY_IN_SECONDS/2

Because, for example, let's see what last division without ceil() returns:

<?php
$nonce = function( $nonce_life = 4 ){
    echo time() / ( $nonce_life / 2 ) ."<br>";
    sleep(1);
};

$nonce(); $nonce(); $nonce(); $nonce();

/* result
753212654
753212654.5
753212655
753212655.5
*/

As we see $nonce_life = 4 sec and in 4 sec nonce code changes two times, but not one time as we expected, because set life of nonce to 4sec...

So if we have nonce_life as DAY_IN_SECONDS - real nonce life becomes DAY_IN_SECONDS/2.

Why it is correct, why we need this logic?

Change History (3)

#1 @dd32
8 weeks ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

Hi @Tkama and welcome to Trac,

The divide-by-two is due to the manner in which WordPress inplements nonces, you may find https://codex.wordpress.org/WordPress_Nonces has some useful information in it, of which I'll rehash some of here.

In WordPress's implementation of Nonces, the nonce/number is generated as being valid for two "ticks", a 'tick' being effectively the number of half-lifes of the time that have occurred within the current time().
In other words, if you generate a nonce with a 24hrs lifespan, WordPress will generate a nonce valid for the current 12hr and the next 12hr time period. As a side effect, this also means that a 24hr lifespan is the upper limit, it's actually somewhere between 12-24hrs.

The /2 in wp_nonce_tick() is integral to that, it splits it into those two ticks (the .0 and the .5). So while it's halving the nonce life there, it's not actually halving the nonce life.

You'll also note that wp_verify_nonce() returns which 'tick' the nonce is currently in:
from: https://developer.wordpress.org/reference/functions/wp_verify_nonce/

return values: (false|int) False if the nonce is invalid, 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.

Hope this helps understand it better!

This is to the best of my knowledge, I may be partially wrong in some aspects of this description, please don't rely upon this for security purposes, I'd advise reading the above link (and the extras in the Resources section() and the original implementation ticket for the details.

#2 @SergeyBiryukov
8 weeks ago

  • Version changed from 4.8.2 to 2.5

Introduced in [7375] for #6266.

#3 @Tkama
8 weeks ago

Hi @dd32 Thanks a lot for such detailed explanation! Now I understand what is what...

Note: See TracTickets for help on using tickets.