In this post, I’ll explain how to reduce the amount of comment spam your WordPress blog receives by using an unobtrusive ‘handshake’ between the two files necessary for a valid comment submission to take place. I’ve written a few different articles on reducing comment spam by means of a challenge response test that the visitor must complete before submitting a comment, but I’m now looking for ways to achieve the same results while keeping the anti-spam method invisible to the visitor.
I’m a big fan of Akismet, but I also want to block as much spam as possible before it is caught by Akisment in order to reduce the number of database entries.
One thing this method does not do is rename and hide the path to the form processing script, but it makes that technique obsolete, anyway.
In the timestamp handshake method, a first timestamp is generated and written as a hidden input field when the post page loads. When the comment is submitted, a second timestamp is generated by the comment-processing script and it and the page-load timestamp are saved as variables. If the page-load timestamp variable is blank, which should be the case if the spambot uses any other page to populate the comment, the script will die. The page-load timestamp is then subtracted from the comment-submission timestamp. If the comment was submitted less than 60 seconds after the post page was loaded, the script dies with a descriptive error message. Hopefully, this will separate the bots’ comments from those left by thoughtful human visitors who have taken the time to read your post. If a human visitor does happen to submit a comment within 60 seconds of the page loading, he or she can click his or her browser’s back button and try resubmitting the comment again in a few seconds.
One drawback is that this method does involve editing a core file – wp-comments-post.php. You’ll have to re-edit it each time you upgrade WordPress, which is a nuisance, I know. The good thing is that if you forget to do this, people can still comment – you just won’t have the anti-spam protection.
Note that the instructions in the following steps are based on the code in WordPress version 2.3 and the Kubrick theme included with that release. You may need to adjust for your version of WordPress.
Step 1 – Add the hidden timestamp input field to the comment form
Open the comments.php file in your current theme’s folder and find the following lines:
<p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"></textarea></p> <p><input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment" />
Add the following line between them:
<p><input type="hidden" name="timestamp" id="timestamp" value="<?php echo time(); ?>" size="22" /></p>
Step 2 – Modify the wp-comments-post.php file to create the second timestamp and perform the comparison
Open wp-comments-post.php and find the lines:
$comment_author = trim(strip_tags($_POST['author'])); $comment_author_email = trim($_POST['email']); $comment_author_url = trim($_POST['url']); $comment_content = trim($_POST['comment']);
Immediately after them, add the following lines:
$comment_timestamp = trim($_POST['timestamp']); $submitted_timestamp = time(); if ( $comment_timestamp == '' ) wp_die( __('Hello, spam bot!') ); if ( $submitted_timestamp - $comment_timestamp < 60 ) wp_die( __('Error: you must wait at least 1 minute before posting a comment.') );
That’s it; you’re done.
Credits
Thanks to Jonathan Bailey for suggesting the handshake in his post at http://www.plagiarismtoday.com/2007/07/24/wordpress-and-comment-spam/.