Stopping WordPress spammer registrations

I used to get 10+ spam user registrations every day on this blog. Not a total flood, but very annoying nonetheless. Today I get none! All thanks to a few lines of code I hacked into wp-login.php. Wanna know how? Read on.

Hacking wp-login.php

You can find, and edit, wp-login.php from within WordPress. Go to “Manage” and “Files” and just select it. Inside this file will be code for registering a new user. Depending on what version of WordPress you’re running, the registration code may look a bit different. Somewhere though you will find a block of code that reads something like:

$user_email = apply_filters( 'user_registration_email', $_POST['user_email'] ); 

// Check the username
...
// Check the e-mail address
...

In my case, I changed this into (bolded code added):

$user_email = apply_filters( 'user_registration_email', $_POST['user_email'] ); 
$user_iq = $_POST['user_iq'];

// Check the username
...
// Check the e-mail address
...

// Check the iq question
if ($user_iq == '') {
    $errors['user_iq'] = __('<strong>ERROR</strong>: Please answer IQ question.');
} elseif ( $user_iq != '<INSERT SECRET ANSWER>' ) {
    $errors['user_iq'] = __('<strong>ERROR</strong>: The email address isn’t correct.');
}

Somewhere further down in the file is a form (name=”registerform”) that must be changed also. From something like:

<p>
    <label><?php _e('Username:') ?><br />
    <input type="text" name="user_login" id="user_login" class="input"
     value="<?php echo attribute_escape(stripslashes($user_login)); ?>"
     size="20" tabindex="10" /></label>
</p>
<p>
    <label><?php _e('E-mail:') ?><br />
    <input type="text" name="user_email" id="user_email" class="input"
     value="<?php echo attribute_escape(stripslashes($user_email)); ?>"
     size="25" tabindex="20" /></label>
</p>

Into:

<p>
    <label><?php _e('Username:') ?><br />
    <input type="text" name="user_login" id="user_login" class="input"
     value="<?php echo attribute_escape(stripslashes($user_login)); ?>"
     size="20" tabindex="10" /></label>
</p>
<p>
    <label><?php _e('E-mail:') ?><br />
    <input type="text" name="user_email" id="user_email" class="input"
     value="<?php echo attribute_escape(stripslashes($user_email)); ?>"
     size="25" tabindex="20" /></label>
</p>
<p>
    <label><?php _e('Give answer to <INSERT SECRET QUESTION>:') ?><br />
    <input type="text" name="user_iq" id="user_iq" class="input"
     value="<?php echo attribute_escape(stripslashes($user_iq)); ?>"
     size="25" tabindex="20" /></label>
</p>

Those are all the changes needed.

The secret question

Obviously, the secret question should be something a spammer couldn’t immediately answer. For a programming blog like this one, it makes sense to make the secret question a programming question. For example, questions like these should weed out 99% of the spammers:

  • What is (5 << 2)?
  • How many nibbles are there in a 32-bit integer?
  • Etc.

It’s best if these questions do not have an answer in the first hit when entered into Google (though it is probably unlikely a spammer would ever go as far as searching for the answer to a custom security question).

Lastly, for this blog I opted for a question that helps weed out a bit more than just spammers from registering, to hopefully help raise the bar of any comments posted. You may or may not want to consider that as an option.

5 thoughts on “Stopping WordPress spammer registrations”

  1. I suspect you’ll be also putting in place a programming ability restriction on profile registration.

    Bit of a pity it can’t be done through the main plugin system. i.e. every time you update you’ll also have to keep the update in sync.

    I seen some example plugins just copy the wp-login system and then modify it, could be possible to create a plugin based on that, still similar sync issues if the wordpress login system changed dramatically.

  2. Interesting that you’ve put a programming question on here, but, a pita if your field of expertise is one that doesnt require knowledge of bitshifts etc. I can see a good many php programmers falling flat on their faces ^_^

    I would say though that if you want to protect the registrations, prevent spammers, and keep this site secure, I’d do the following:

    – Never edit core wordpress files
    – Update this website from WordPress 2.2 to 3.0 ( your changes are pointless when there’s a list of known fixed exploits as long as your arm )
    – Use a plugin to do this ( they do exist! ) There’s one called Block-Spam-By-Math-Reloaded you can use as a basis for this, and it’ll protect comments/logins/registrations

  3. Of course I had to create an account to see what the problem was. I sort of think ^ 0x22 would’ve given a slightly more interesting answer, while being no more difficult to solve.

    I see there’s a reCAPTCHA to post–where the spammers getting through that, as well?

  4. @lantree and @tarendai: That I’m expecting a modicum of programming skill of the registrants is, of course, deliberate! Perhaps harsh, but if someone can’t get past the question, it’s my opinion that their programming skills are weak or that they’re sloppy, and their comments are likely to be weak or sloppy too. Quality over quantity!

    @Clayton: between TanTanNoodles (6965 spam comments rejected), Akismet (3,344 spams caught), administration on first posts, and reCAPTCHA, the spam itself isn’t so much a problem. Just the user registrations themselves.

    @tarendai: Point definitely taken on the updating. If only it wasn’t such a PITA. It should be a one-button solution!

  5. I created an account to see what the problem was. I was scared initially that I will fail the level-0 programming test but it was a relatively simple one and probably every programmer in game/graphics/movie industry will pass this test. I have followed this blog regularly (though there have been only few posts, of late) and use the Real Time Collision Detection book for every day work (absolutely love the contents and organization of the book).

Leave a Reply