2

Can Wordpress Nonces be used to protect against Login CSRF? https://codex.wordpress.org/WordPress_Nonces

I glanced through the code for the function and it seems to only be using the User ID for verification, that means that the attacker and victim will have the same nonce? Is this really correct?

2

Yes, Wordpress nonces can protect against login CSRF.

Wordpress nonces can be applied to URLs and also forms, like the login form:

To add a nonce to a form, call wp_nonce_field() specifying a string representing the action. By default wp_nonce_field() generates two hidden fields, one whose value is the nonce and one whose value is the current URL (the referrer), and it echoes the result. For example, this call:

wp_nonce_field( 'delete-comment_'.$comment_id );

might echo something like:

<input type="hidden" id="_wpnonce" name="_wpnonce" value="796c7766b1" />
<input type="hidden" name="_wp_http_referer" value="/wp-admin/edit-comments.php" />

Usually, nonces are created attached to a user that is logged in because it makes sense to protect users that are logged in. But login CSRF is special because it can be used to target logged out user by logging them in.

Looking through the wp_create_nonce code I can see that nonces are created for logged out users as well:

function wp_create_nonce($action = -1) {
    $user = wp_get_current_user();
    $uid = (int) $user->ID;

    if ( ! $uid ) {
        $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 );
}

Then use wp_verify_nonce to verify the nonce. It returns false if the nonce in invalid. Otherwise, returns an integer with the value of:

  • 1: if the nonce has been generated in the past 12 hours or less.
  • 2: if the nonce was generated between 12 and 24 hours ago.
0

I glanced through the code for the function and it seems to only be using the User ID for verification, that means that the attacker and victim will have the same nonce? Is this really correct?

Looking at the code it can be observed that the session identifier is used as part of the nonce generation:

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

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

This ties the session token to the nonce, so if the form was submitted using the nonces from another session (e.g. the attacker's nonce), wp_verify_nonce would not match it up, protecting against login CSRF.

See this answer for more on this technique (with anonymous cookies section).

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.