Using AJAX on your WordPress website can greatly enhance the user experience on your website. But, like all things web, you should properly secure your AJAX functions.
One of the easiest ways to begin to secure your AJAX functions is to use a WordPress AJAX nonce, which is just a way to verify that all AJAX calls are originating from your website.
What is a Nonce?
WordPress describes nonces as “a one-time token generated by a website… This could prevent unwanted, repeated, expired, or malicious requests from being processed.”
In other words, a nonce is a unique key that your website creates that allows you to verify actions. For the purposes of this article, we’re going to focus on using nonces to ensure that requests are originating from our own website.
How to Implement a WordPress AJAX Nonce
Implementing a nonce for your AJAX functions in WordPress is actually fairly straightforward. First, let’s start by generating the nonce. The proper way of doing this is by localizing your javascript files.
[code lang=”php”]
$params = array(
‘ajaxurl’ => admin_url(‘admin-ajax.php’, $protocol),
‘ajax_nonce’ => wp_create_nonce(‘any_value_here’),
);
wp_localize_script( ‘my_blog_script’, ‘ajax_object’, $params );
[/code]
This code will create an object containing values for:
- ajaxurl – This is the absolute address, taking into account http:// or https://, to your ajax processing script. This script is in the wp-admin folder, but can be used for front end ajax scripts as well.
- ajax_nonce – This is our nonce that we check in our ajax function. Notice how I used the string ‘any_value_here’ within the wp_create_nonce function… You can use any string, but be sure to remember what you use, because we will need to use the same string when we check the AJAX nonce.
We can access the values in this object like this: ajax_object.ajax_nonce.
Now that we have the AJAX nonce and URL setup, it’s time to go ahead and setup our AJAX call in our javascript file. Although I will be using the $.ajax function in this example, you can also use the $.post function. Here is an example of how to setup your AJAX call.
[code lang=”javascript”]
$.ajax({
type : "post",
dataType : "json",
url : ajax_object.ajaxurl,
data : ‘action=get_posts_commented&email=’+user_email+’&security=’+ajax_object.ajax_nonce,
success: function(response) {
// You can put any code here to run if the response is successful.
// This will allow you to see the response
console.log(response);
}
});
[/code]
Notice how we are adding the ajax_nonce to the end of our parameter string. We can then access this in the AJAX processing script using $_POST[‘security’].
Alright, now that we’ve got our WordPress AJAX call setup, it’s time to go ahead and setup the PHP function that will process our AJAX call. Here is an example:
[code lang=”php”]
add_action(‘wp_ajax_get_posts_commented’, ‘get_posts_commented’);
add_action(‘wp_ajax_nopriv_get_posts_commented’, ‘get_posts_commented’);
function get_posts_commented(){
check_ajax_referer( ‘any_value_here’, ‘security’ );
$email = urldecode($_POST[’email’]);
global $wpdb;
$results = $wpdb->get_results($wpdb->prepare("
SELECT
comment_post_ID
FROM
{$wpdb->comments}
WHERE
comment_type = ” AND comment_approved = 1 AND comment_author_email = ‘%s’";,
$email), ARRAY_A);
echo json_encode($results);
exit;
}
[/code]
Notice that at the top of this WordPress AJAX function there this line:
[code lang=”php”]
check_ajax_referer( ‘any_value_here’, ‘security’ );
[/code]
This function is how we check the WordPress AJAX nonce. The first parameter is the key we assigned when creating the ajax_nonce above. In this example that is ‘any_value_here’. The second parameter lets the function know what parameter of the request to look in for the AJAX nonce.
If the nonce is not set or incorrect, then check_ajax_referrer() will cause the AJAX call to die, protecting your AJAX call from invalid requests.
Conclusion
Checking for WordPress AJAX nonces is not a foolproof security solution for your AJAX calls, but it is definitely a good step in the right direction. If you’re making database calls in your AJAX function I would suggest you look at using $wpdb->prepare
to sanitize variables used in your SQL statements.
Leave a Reply to Chiedozie JeffreyCancel reply