Recently LunchTable received an influx of spam registrations: marked by similar-looking nonsensical usernames, “real names” that didn’t match their gender, and email addresses on adult sites. I didn’t want to use CAPTCHA to mitigate this, because I personally die a little inside at each CAPTCHA encounter, so I took another route.

With a little help from StackOverflow (can’t find the link now, will update), I found a clever solution that banks on spam scripts not executing Javascript. Less than 12 hours of being live captured and prevented two spam registrations. I start by adding a hidden input field to my registration form and filling it with default text:

<input type="hidden" id="robot" name="beep-beep-boop" value="iamspam" />

Next, I add a little Javascript to change this value to a numeric value, and subsequently increment it every second (this will come in handy later):

var botZapper = function() {
    if (document.getElementById("robot")) {
        a = document.getElementById("robot");
        if (isNaN(a.value) == true) {
            a.value = 0;
        } else {
            a.value = parseInt(a.value) + 1;
        }
    }
    setTimeout(botZapper, 1000);
}
botZapper();

Finally, on the server side, I do a simply check (in PHP):

$botTest = $_POST['beep-beep-boop'];
if ( $botTest == "iamspam" || !is_numeric($botTest) || $botTest < 10) {
    // This appears to be spam!
    header("Location: /");
    exit;
}
// ...database INSERT code untouched by bots...

This checks if any of the conditions are true, indicating a bot:

  • First, if the value hasn’t changed; meaning the user didn’t have Javascript enabled.
  • If the submitted value is other textual information we didn’t expect.
  • If JS was enabled, but the form was submitted within 10 seconds.

If these tests fail, I mercilessly redirect the bot to the home page with no “fail” message! My scorn is certainly felt.

Your time threshold will definitely vary depending on the length of your form, and you will need to¬†accommodate¬†users without Javascript enabled at all. However, at the time of this sentence’s writing, I’ve captured four attempted spammings from China, all who never updated the hidden input field (failing at the first test).

$ logout

Advertisements