WordPress

No More Comment Spam

Since moving my comments from Disqus back to native WordPress comments I was getting a lot of spam comments a couple every minute. I had the suggested plugins installed like Akismet.

Akismet is owned my automattic the same guys that make WordPress and it's the recommended plugin to use to solve any spam comment problems you might be facing. But even with this installed I was still getting spam comments all the time.

If I left this for a couple of days then the database would start to be filled with a lot of spam comments. I had to find a new solution on how to remove the spam comments from the WordPress site, as when using Disqus I wouldn't get any spam comments in my WordPress database.

Thinking about what disqus did that would made sure no spam comments can come through and this is using JavaScript to load disqus onto the page, making sure that any spam bots can't post the form as JavaScript isn't loaded by bots.

Therefore Why can't we use JavaScript with native WordPress comments and add a hidden field onto the form, then on posting the comment we check if this hidden field is posted, if it's not then we reject the comment.

Creating The Plugin

First we need to create a plugin that's going to add a JavaScript file to the page and another function to process the $_POST of the comment form.

<?php
/*
* Plugin Name: Paulund No More Comment Spam
* Plugin URI: https://paulund.co.uk
* Description: Remove comment spam from your WordPress site by checking for a JavaScript injected element
* Version: 1.0
* Author URI: https://paulund.co.uk
* License: GPL2
*/
class No_More_Comment_Spam
{
    /**
     * No_More_Comment_Spam constructor.
     * 
     * Add the scripts and preprocessor comment
     */
    public function __construct()
    {
        add_action('wp_enqueue_scripts', array($this, 'add_scripts'));
        add_action('preprocess_comment', array($this, 'check_for_element'));
    }

    /**
     * Add JS which will add the element to the page
     */
    public function add_scripts()
    {

    }

    /**
     * Check for the can comment element
     * 
     * @param $commentdata
     * @return mixed
     */
    public function check_for_element($commentdata)
    {

    }
}
new No_More_Comment_Spam();

As you can see in the constructor of the class we have 2 add_action() functions, one for wp_enqueue_scripts to add the JavaScript file and preprocess_comment to process the comment data from the comment form.

Add JavaScript File

/**
 * Add JS which will add the element to the page
 */
public function add_scripts()
{
    wp_enqueue_script('add-comment-spam-js', plugin_dir_url(__FILE__) . 'js/no-more-comment-spam.js', array('jquery'), false, true);
}

Now we can create the JavaScript file to add the form element to the page. For this we just check for the commentform ID in the HTML and then append a new input hidden type to the form with a value of 99999.

$j=jQuery.noConflict();

$j(document).ready(function()
{
    if($j('#commentform').length > 0)
    {
        $j('#commentform').append('<input type="hidden" id="can-comment" name="can-comment" value="99999" />');
    }
});

On the server side we need to check for this can-comment element and check the value is still the same and if it is then we allow the comment to go through.

Preprocess Comment

In this we need to check that the can-comment element exists if it does that we know the visitor had JavaScript on and is a real user and we can accept the comment. If the can-comment doesn't exist then the user could either be spam or not have JavaScript turned on.

/**
 * Check for the can comment element
 * 
 * @param $commentdata
 * @return mixed
 */
public function check_for_element($commentdata)
{
    if(!isset($_POST['can-comment'])) {
        wp_die('Are you spam?');
    }

    if(empty($_POST['can-comment']))
    {
        wp_die('Are you spam?');
    }

    if($_POST['can-comment'] != 99999)
    {
        wp_die('Are you spam?');
    }
        
    return $commentdata;
}

Since having this small plugin installed I've gone from getting a spam comment every minute to ZERO spam comments, nothing filling up my database with spam comments.

You can either create this same plugin for your WordPress sites or Paulund members can download this same plugin and just install it on your site.

Back to top

Members Download

Comments

  1. Nils says:

    Nice Tip but there is already a plugin like this online called NoSpamNX and it works really well

    1. Paul says:

      Thanks Nils, I find there's normally already a plugin to do something you want, the beauty of WordPress :). I still like making my own plugins though then you don't get anymore bloat in the plugin that you might not use.

  2. Dylan says:

    Ah, the good old reverse honeypot. Much more effective I think.

    What I used to do was create a checkbox and hide it with CSS. The idea was that most spam bots would see the checkbox and enable it just in case. Since a human could not see the checkbox, a human would leave it unchecked. Not foolproof, but it cut my spam down considerably.

    Of course, when I implemented something similar to what you did, my spam was completely eliminated. Your solution is much more elegant than mine though haha.

    1. Paul says:

      That's a good one. Same result so suppose it doesn't matter which approach you take. Did you find all spam bots would actually enable it?

      1. Dylan says:

        Most bots enabled it, but the simplest bots would not and just fill in the default fields, allowing the comment to be posted. This is why I prefer your version; it's far more effective!

  3. Would probably be a little more secure if you used a nonce instead of a set 99999 value.

    1. Paul says:

      Hi Chris, yes it will do but the field needs to added with JS to stop bots, I guess this could be setup with an additional AJAX request to setup the nonce.

  4. Andrea says:

    We use https://en-ca.wordpress.org/plugins/anti-spam/ which I think does the same approche for capturing spammers.
    If not, you can contribute and add your idea there.

    Andrea,
    @appmiin

    1. Paul says:

      Thanks I'll have a look and see what they do.

  5. Don't a lot of these bots make comments without using the forms?

    1. Paul says:

      Yes Jeremy, I would assume the majority of them would just send a POST request to https://paulund.co.uk/wp-comments-post.php the standard URL for the WordPress comment form. This is why this solution works so well because they won't be using JavaScript within a browser so the additional can-comment field isn't created by them and therefore the comment is rejected. Meaning we only allow comments from browsers that render JavaScript, which is a large percentage of normal users and not bots.

  6. Nath says:

    Great post! Think i'll use this on my clients sites to stop spam...thanks Paul!

  7. Sebastian says:

    Well the theory is good, but you will get some angry users, if they won't or can't use JavaScript.
    I think it's better to place the honeypot input permanently in the form. So you won't fail without JS.

    1. Paul says:

      Well it will just mean they can't comment, there's other ways of "commenting" on an article, you can email the writer, tweet, facebook, G+, write your own reply article. I was using Disqus before so user's wouldn't be able to comment on that.

Leave a Reply

Your email address will not be published. Required fields are marked *