BuddyPress anti-spam techniques – jQuery enabled + time to submit reg form

This one is by far the best technique I’ve found to curb the (current…) spate of BuddyPress spam registrations.

It covers three aspects: ensuring the user has JavaScript / jQuery and cookies enabled in their user agent, and also rejects bots / scripts which seem to always manage to load the registration form and then submit it in well under 10 seconds (as is the case with every single BP spam signup I’ve run forensics on in the last several months).

Note that these instructions are a little terse – I’m not here to teach you best practice techniques involved with coding against WP or BP, or coding in PHP or jQuery in general :p

So… Let’s get started!

Firstly, you’ll want to load your own external JS / jQuery file, and set up a few things you’ll need later. Add the following to your (child) theme’s functions.php:

function add_my_jquery_stuff() {
    wp_enqueue_script('myjquery',get_bloginfo('stylesheet_directory').'/my.js',array('jquery'));
    if ($pagenow == 'register.php') {
        if (isset($_POST['signup_submit'])) echo '<script>ispost = true;</script>';
        else {
            echo '<script>var ispost = false;var timestamp = '.time().';</script>';
            wp_enqueue_script('jquery-cookie',get_bloginfo('stylesheet_directory').'/jquery.cookie.js',array('jquery'));
        }
    }
}
add_action('wp_enqueue_scripts','add_my_jquery_stuff');

You should at least change “my” in the above code to something more unique to avoid namespace clashes. The “array(jquery)” argument simply ensures that WP has loaded the jQuery library before enqueueing your script file.

You can test whether the current page is the register one however you like – obviously, I usually use “if ($pagenow == ‘register.php’)”.

If you already enqueue an external, custom js file then adjust the above to suit…

Then, create an empty file called my.js (or whatever matches the filename argument you used above) to the root folder of your (child) theme.

Next, you’ll need to install the jQuery-cookie plugin. Just plonk jquery.cookie.js into your (child) theme root folder – it’s already called via the function above.

Onto the jQuery… Add the following to your external js file:

jQuery(document).ready(function($) {
    if ($(location).attr('pathname').substr(0,9) == '/register') {
        if (!ispost) $.cookie('myregcookie',timestamp);
    }
}

Of course, ignore the document.ready wrapper if you already have an established js file, and adjust the cookie name to suit your application / taste.

Now add the following to your functions.php file:

function my_check_reg_cookie() {
    if (!isset($_COOKIE['myregcookie']) || time() - $_COOKIE['myregcookie'] < 10) {
        global $bp;
        wp_redirect(home_url().'/spam-prevention');
        exit;
    }
}
add_filter('bp_core_validate_user_signup','my_check_reg_cookie');

And lastly, create a new page in your WP admin backend – call it Spam Prevention (make sure it’s slug is spam-prevention), and make it say something like:

If you’re seeing this page, you’ve done something that looks a little spammy.

It could be that you simply haven’t got JavaScript or cookies enabled. If that’s that case, then should you know how to turn it back on for our site – or else you might need a better or more recent browser :-)

Spammers like to use automated software and lots of other tricks to bypass the very techniques we use to make sure only our members and other, legitimate folk are using our site.

If you are a real person and / or a legitimate member, then we apologise for the inconvenience and invite you to contact us so that we can get you sorted as soon as possible :-)

That’s it! Here’s how it works: When your registration page is hit, a Unix timestamp is generated by PHP and passed to jQuery as a variable. jQuery then sets a cookie whose value is the timestamp. When the registration form is submitted, the existence of the cookie is checked. If it doesn’t exist, it’s a fail. If it does, and the timestamp it contains is less than 10 seconds old, it’s a fail. If it’s a fail, the user is redirected to the Spam Prevention page (and the registration attempt is ignored).

Have an appropriate amount of fun 🙂