wp_verify_nonce vs check_admin_referer

The question:

What is the difference, which one should I use?

I know that wp_verify_nonce checks the time limit, and check_admin_referer I think calls wp_verify_nonce as well as checking for an admin url segment, but I’m a bit confused on which one I should use and when.

Thanks for the clarity.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

I thought that check_admin_referer checked the nonce (it does call wp_verify_nonce, and the referring url. After digging into the core code I realised that it did not do this. Thinking it was a bug I reported it, and Ryan Boren replied with the following:

Actually, if the nonce is valid the referrer should not be checked.
The unreliability of referrers is one of the reasons that nonces are
used. Nonces replace referrer checking entirely. The only time we
check the referrer is when handling the -1 backward compatibility
condition. -1 means that someone is not using nonces so we fall back
to referrer checking. This usage is now very rare.
check_admin_referer() is badly named now that it almost never does
referrer checking. It would be better named something like
check_nonce(), but we keep it as is for back compat and old times
sake.

So there is in fact there is no difference.

Method 2

NO! BEWARE !!!

Don’t count on check_admin_referer() without correct parameters! Because, in some cases it may not die() (as opposed to your expectations), instead it will just return the false response.

Look through the outlined behavior of source code logic:

function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
    $result   = isset( $_REQUEST[ $query_arg ] ) ? wp_verify_nonce( $_REQUEST[ $query_arg ], $action ) : false;

    //Now, "die() check"
    if ( ! $result && ( -1 !== $action || strpos( wp_get_referer(), admin_url() ) !== 0 ) ) {
        die();
    }
    return $result;
}

So, you need to realize what the logic does. Here breakdown:

A) if you call just check_admin_referrer() without parameters:

  • REMEMBER, it will use the automatically built-in _wpnonce value (that is
    safe, but still remember to have exactly that field when submitting).
  • As you called it without paremeters, it uses default -1 value for action, leading the die() check to be skipped and function will not die()
  • So, you should always use (when calling without parameters):

if ( check_admin_referer() ) exit;

B) if you want check_admin_referrer to die automatically, then you should always create your nonces & call it with parameters:

check_admin_referrer($action_name, $name_field );


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment