Nonces and Cache

It’s clear that form submissions and AJAX requests, especially sensible ones, need “nonces” to avoid certain exploits.
However, with heavy use of caching systems it becomes harder to generate them and output fresh nonces instead of cached ones.

To solve the problem I thought about creating an AJAX function that returns a fresh nonce, to be requested before a form is submitted. This nonce will be then appended to the form as a hidden field.

Do you think it’s a safe approach?

PHP function to return a fresh nonce:

function create_nonce() {
    return wp_create_nonce('my-nonce');
}

add_action('wp_ajax_create_nonce', 'create_nonce');
add_action('wp_ajax_nopriv_create_nonce', 'create_nonce');

Submit the form (request() is a custom function I’ve created to easily make ajax requests):

$('form').on('submit', function(e){
    e.preventDefault();
    var $form = $(this);

    request('create_nonce', function(nonce){
         // Append the fresh nonce to the form
         $form.append('<input type="hidden" name="nonce" value="'+nonce+'">');

         // Proceed with the form submission...
    });
});

1
1

I know this question is ancient, but no, it’s not very secure.

Anyone with knowledge of the AJAX endpoint would be able to generate valid nonces, which defeats the purpose in the first place.

That being said, nonces are a low level defence in the first place: they only stop the simplest of attacks. A clever attacker would have crawled your homepage to begin with, and gobbled up all the nonces (which has a default lifespan of 24 hours these days), and then just use that nonce for the attack. Your AJAX endpoint simply makes that task slightly easier.

EDIT

As Janh pointed out, as long as nonces are user specific, meaning a nonce will only work for a specific user, if so, an ajax generated nonce should be fine. You will probably need to send a bit more information via the AJAX endpoint though, so the returned nonce is tied to the correct user.

Leave a Comment