0

I'm trying to reproduce the wordpress "nonce" parameter. How is it generated? How is it related to the cookies?

From codex.wordpress.com:

Nonces are generated using a key and salt that are unique to your site if you have installed WordPress correctly. NONCE_KEY and NONCE_SALT are defined in your wp-config.php file, and the file contains comments that provide more information.

And so this I get out (default-constants.php):

function wp_cookie_constants() {
    /**
     * Used to guarantee unique hash cookies
     *
     * @since 1.5.0
     */
    if ( !defined( 'COOKIEHASH' ) ) {
        $siteurl = get_site_option( 'siteurl' );
        if ( $siteurl )
            define( 'COOKIEHASH', md5( $siteurl ) );
        else
            define( 'COOKIEHASH', '' );
    }

    /**
     * @since 2.0.0
     */
    if ( !defined('USER_COOKIE') )
        define('USER_COOKIE', 'wordpressuser_' . COOKIEHASH);

    /**
     * @since 2.0.0
     */
    if ( !defined('PASS_COOKIE') )
        define('PASS_COOKIE', 'wordpresspass_' . COOKIEHASH);

    /**
     * @since 2.5.0
     */
    if ( !defined('AUTH_COOKIE') )
        define('AUTH_COOKIE', 'wordpress_' . COOKIEHASH);

    /**
     * @since 2.6.0
     */
    if ( !defined('SECURE_AUTH_COOKIE') )
        define('SECURE_AUTH_COOKIE', 'wordpress_sec_' . COOKIEHASH);

    /**
     * @since 2.6.0
     */
    if ( !defined('LOGGED_IN_COOKIE') )
        define('LOGGED_IN_COOKIE', 'wordpress_logged_in_' . COOKIEHASH);

    /**
     * @since 2.3.0
     */
    if ( !defined('TEST_COOKIE') )
        define('TEST_COOKIE', 'wordpress_test_cookie');

    /**
     * @since 1.2.0
     */
    if ( !defined('COOKIEPATH') )
        define('COOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_option('home') . '/' ) );

    /**
     * @since 1.5.0
     */
    if ( !defined('SITECOOKIEPATH') )
        define('SITECOOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_option('siteurl') . '/' ) );

    /**
     * @since 2.6.0
     */
    if ( !defined('ADMIN_COOKIE_PATH') )
        define( 'ADMIN_COOKIE_PATH', SITECOOKIEPATH . 'wp-admin' );

    /**
     * @since 2.6.0
     */
    if ( !defined('PLUGINS_COOKIE_PATH') )
        define( 'PLUGINS_COOKIE_PATH', preg_replace('|https?://[^/]+|i', '', WP_PLUGIN_URL)  );

    /**
     * @since 2.0.0
     */
    if ( !defined('COOKIE_DOMAIN') )
        define('COOKIE_DOMAIN', false);
}
  • 1
    I'm having trouble figuring out what exactly your question is. What makes you think NONCE_KEY/SALT have anything to do with cookies? – AndrolGenhald May 22 '18 at 20:39
  • See the wp_salt function. And look at who calls it. The function (not that specific salt as their are so many) is used to authenticate session cookies. – Dan D. May 23 '18 at 6:41
  • I don't understand what the question is - what is it that you want to know? How the nonce parameter is generated? – Anders May 23 '18 at 7:43
  • yes i want to know how the nonce (ajax) parameter is created :) – Robert Beran May 23 '18 at 7:49
2

To find out, look at the WP source code.

Nonces are generated by the wp_create_nonce function in pluggable.php. The real deal is this:

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

Where:

  • $i is a form of timestamp (it increases by one at a fixed time interval, and a nonce has a lifetime of two such intervals).
  • $action specifies what action the nonce is for (defaults to -1).
  • $uid is the user ID (special rules apply if the user is logged out).
  • $token is the session ID for the current session.

Taking a closer look at the wp_hash function (located in the same file), we find this:

function wp_hash( $data, $scheme = 'auth' ) {
    $salt = wp_salt( $scheme );
    return hash_hmac( 'md5', $data, $salt );
}

So it's a MD5 HMAC. The hash_hmac function is a PHP core function. The variable that for some reason is called $salt is the HMAC key.

So what is the $salt? Clearly it's dependent on $scheme that is "nonce" in our case. For more info, take a look at the wp_salt function. In the comments, you'll find this:

Salts are created using secret keys. Secret keys are located in two places: in the database and in the wp-config.php file. The secret key in the database is randomly generated and will be appended to the secret keys in wp-config.php.

For more details on exactly where it reads the keys, see the actual code. As far as I can tell, it's completely unrelated to any cookies.

TL;DR: The nonce is a MD5 HMAC of a timestamp, the action, the user id and the session id, keyed with a secrets stored in wp-config.php and the database.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.