Securing your WordPress plugin AJAX calls using nonces

In my last article on this topic I wrote about proper way of implementing AJAX with jQuery in your WordPress plugins. In this article I will show you how to implementing AJAX with jQuery in your WordPress plugins in more secure way by using WordPress nonces. Cryptographic nonce is number passed during communication whose purpose is to prevent someone sniffing authenticated communication to commit replay attack

by replaying captured communication request. Nonces protect you because every request has its own unique nonce, this way both sides can detect replay attack attempts. Now lets take a look at how WordPress implements nonce security.

Keep in mind that WordPress nonce is a bit different than standard cryptographic nonce. WordPress nonce is not used only once, instead it remains valid for 12 to 24 hours after it has been generated. This decreases both your level of protection and performance impact of generating new nonce on every request. But we should use them when ever possible to make our code as close to bulletproof as possible.

In the line 7 of the preceding code block we are using wp_create_nonce() to generate nonce. We must remember both AJAX action 'my_plugin_my_action' and AJAX action nonce 'my_plugin_my_action_nonce' slugs because we will use them when we try to verify AJAX call supplied with this nonce. For convenience we will use same naming convention on our client side. Now here's the Javascript from my last article on this topic modified to use nonce security:

What is new are lines 3 and 6. Line 3 sends nonce received from PHP side during page load using wp_localize_script. This nonce will be verified by our AJAX action callback on PHP side. Line 6 is here because if nonce verification is successful we will receive new nonce along with AJAX data. This nonce will stay unchanged most of the time because WordPress nonces are valid for 12-24 hours after being generated but our AJAX calls will work even after nonce has changed because we update it each time our AJAX call returns. Now here's our PHP AJAX action callback modified to implement nonces:

Just one more thing. If you're planing to make your plugin compatible with PHP caching plugins like WP Super Cache or W3 Total cache you will not be able to reliably use nonces because nonces won't be generated on each page load.