• Resolved Beda

    (@bedas)


    I am struggling to understand something related to nonce_user_logged_out hook and its uid.

    So according the doc, when we wp_create_nonce and the user is logged out, the nonce generator assumes uid = 0.
    Thus I apply the nonce_user_logged_out filter, and pass rand() as uid (or time() or whatever _unique_ value that is generated anew and different from any previous everytime the form is loaded

    This seems to break check_ajax_referer. In fact, check_ajax_referer only appears to validate if the uid is “fixed”.

    For example, if I pass 123 to uid then it validates, if I pass time() or rand() it does not.

    I do understand this is because the values I use are truly unique: not once the same. However I do not understand is, it appears that when the form is submitted (via AJAX), and the JS sends the POSTed data with the (correct) nonce to the PHP callback, a NEW nonce is generated??

    The form is not loaded again.
    In fact, if we observe the HTML of the form – the nonce will change each time the form reloads, yes, but of course stay the same as long we do not reload the form.
    The ajax POST request does NOT reload the form, it merely passes the data to the PHP callback and in that callback the nonce check happens, which SHOULD check for the nonce generated when the form was loaded, nor for some new nonce.

    If it is not clear – here the logic is illustrated with some dummy code:

    1. add_filter( 'nonce_user_logged_out', 'make_uid_unique', 10, 2 );
    2. Callback make_uid_unique returns $uid = time(); or $uid = rand(); if $action is my_nonce
    3. HTML Form has <input type="hidden" name="nonce_s" value="<?php echo esc_attr( wp_create_nonce( 'my_nonce' ) ); ?>">
    4. jQuery ajax POSTs nonce: $('input[name="nonce_s"]').val(),
    5. PHP callback does check_ajax_referer( 'my_nonce', 'nonce' );

    This fails, even if the Nonce visible in nonce_s input field is the exact same as passed in the ajax POST nonce.
    As soon you pass for example the IP, or any other static value in nonce_user_logged_out filter, it works.

    I do not understand why. It appears to me the nonce is regenerated on AJAX post request, but that does not make sense, since the PHP for that is not executed, at all, unless the page is reloaded.

Viewing 1 replies (of 1 total)
  • Thread Starter Beda

    (@bedas)

    Yeah ok. Nice rubberduck session.

    I answered my question in my own question:
    > the nonce is regenerated by check_ajax_referer() with the same UID, time and action – it is not retrieved from some session storage. Thus, it tries to validate a nonce that is generated with a new random or time value… and therefore fails.

    Closing as I completely missed the point 😛

Viewing 1 replies (of 1 total)
  • The topic ‘nonce_user_logged_out and unique UIDs’ is closed to new replies.