7

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...
    });
});
3
  • 2
    Are you using exceptionally long caching times or on-demand invalidation only? Nonces are good for 24 hours (as far as I remember), this is way longer than typical caching interval.
    – Rarst
    Nov 18, 2013 at 21:12
  • I considered it, but I thought it might be difficult to syncronize. This article explains it very well, however to setup cron jobs is a barrier if I wish to distribute the code as a plugin. But thanks for your comment!
    – gyo
    Nov 19, 2013 at 10:34
  • Is there any way you could publish your request() function. I'd love to see how this works in it's entirety.
    – user62395
    Oct 21, 2014 at 15:03

1 Answer 1

3

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.

3
  • 1
    It doesn't really add any insecurities, though. WP's nonces are user specific, so you'd only be able to quickly generate nonces for your user, and you don't really need to do that as you pointed out. Nonces are used to defend against attacks on other users, for which they are fine, and you can't create a valid nonce for another user with this method.
    – janh
    Dec 29, 2017 at 15:29
  • You're right, if they are user specific then it should suffice. I'll update the above.
    – DarkNeuron
    Dec 29, 2017 at 15:36
  • WP takes care of that automatically. As long as the AJAX-request contains the authentication cookies (and it will, usually), the nonce will be tied to that user.
    – janh
    Dec 29, 2017 at 15:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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