Image / math hybrid captcha version 2, vastly improved

Comments (11)

My first step in the process to keep comment spam at bay on sNews was to re-write my image/math hybrid captcha mod. Since I installed the first version of this on my main site here over a month ago, I haven't had any comment spam, while I do still receive comment spam on my theme demo sites, that gives me anecdotal evidence that it is at least somewhat effective against bots.

It wasn't without problems though, first it can be resource intensive if you get a lot of hits because it generates a new image on the fly and then deletes the image after serving. The second problem is it used a second file (capgen.php) to pass a key to via GET, so it could create the image, this key could also be decoded with some effort.

If you're unfamiliar with this mod, what it does is it replaces the mathCaptcha text (the "4 + 5 =" part) with an image, so spam bots will first have to decode the image to be able to do the math, they can't just scan the text with a regular expression.

With this new version I have eliminated both of these problems, it's much easier to use, and I've added these improvements to version 2;

  1. The image creation is now included within the mathCaptcha function, and the generated images will be saved into the "captchas" folder on your server (you will need to create the captchas folder).
  2. The function will first check your captchas folder to see if the image exists before generating a new one. If the captcha image doesn't exist, it will generate it on the fly and then serve it statically.
  3. You can use your own personal salt, so a bot programmer can't determine the naming convention of the images.
  4. We are adding another variable salt, the day of the month via PHP, so the key will be new for every day of the month. So your server will need to create a maximum of 81 images per day, a huge resource saver if you get Dugg.

The end result will be 9($x) * 9($y) * 31($mathkey) * 160bytes average = total of 2511 images possible, around 392KB space needed, not much at all. I included some basic checking so if your host disallows PHP from creating images, it will default back to the old text style captcha.

To implement (or upgrade from the first version) is very simple, BACK-UP your snews.php file and work off of a copy. Now replace the function mathCaptcha() with the one below, be sure to change the $my_salt variable and create a folder for your captcha images and change the $my_captcha_folder path;

// MATH CAPTCHA
function mathCaptcha() {
    $my_salt = "123"; // enter your own personal salt here to ensure your images are different from everyone else's
    $my_captcha_folder = 'captchas/'; //create this directory in the same directory as your snews.php
    $mathkey = date('d'); // new key for every day of the month, max 81 images in a day will save tons of resources on busy sites
    $x = rand(1, 9);
    $y = rand(1, 9);
    $_SESSION[_SITE.'mathCaptcha-digit'] = $x + $y;
    $math = '
        <p><label for="calc">
            * '.l('math_captcha').':
        </label><br />';
    if(!function_exists('imagecreate') || !is_dir($my_captcha_folder) || !is_writable($my_captcha_folder)) { // either php isn't configured to create images or the captcha folder doesn't exist/isn't writable so let's fall back to the standard text mathCaptcha
        $math .= $x.' + '.$y.' = ';
    } else {
        $key = $x.$my_salt.$mathkey.$y;
        $md5_name = md5($key).'.png'; // name of png image we want
        if(!file_exists($my_captcha_folder.$md5_name)) { // image doesn't already exist
            $my_img = imagecreate(80, 20); // let's create a new one using the day of the month, my salt and the $x & $y
            imagesavealpha($my_img, true); 
            $trans_color = imagecolorallocatealpha($my_img, 0, 0, 0, 127); 
            imagefill($my_img, 0, 0, $trans_color);
            $text_color = imagecolorallocate($my_img, 0, 0, 0);
            imagestring($my_img, 5, 10, 3, "$x + $y =",
            $text_color);
            imagesetthickness($my_img, 5);
            imagepng($my_img,$my_captcha_folder.$md5_name); // save the image to the captchas folder
        }
        $math .= '<img src="'._SITE.$my_captcha_folder.$md5_name.'" alt="" style="vertical-align:middle" />'; // serve the image
    }
    $math .= '
        <input type="text" name="calc" id="calc" style="vertical-align:middle" />
        </p>';
    return $math;
}

All set, now upload your modified snews.php file and delete the old capgen.php from version 1 (if you had it installed) and you're in business.

bookmark / share this: Bookmark and Share
rated 4.64/5 (11 votes)


11 comments

Add a new comment »

Matt Matt (Admin) said:
Feb 25th, 2009 at 11:53 am

Test comment to make sure it works... oh hell yeah... heh... I love this mod, one of my personal favorites.


Mark Mark said:
Feb 25th, 2009 at 12:06 pm

Wow, you are really making some great mods/themes for sNews.

Keep up the good work!


Matt Matt (Admin) said:
Feb 25th, 2009 at 12:39 pm

Thanks a lot Mark!

By the way, if someone wants to use this on a webpage with a dark background, they can change the line;

$text_color = imagecolorallocate($my_img, 0, 0, 0);

the last 3 variables are the respective RGB decimal colors, so if you want white text, you'd use;

$text_color = imagecolorallocate($my_img, 255, 255, 255);

dark slate gray (aka #2F4F4F in hex) would be;

$text_color = imagecolorallocate($my_img, 49, 79, 79);

and so on.


Patric Patric said:
Feb 26th, 2009 at 1:55 pm

Confirming it's awsome'ness. Great, correction, freaking great mod Matt... Thanks a bunch.


Matt Matt (Admin) said:
Feb 27th, 2009 at 5:00 am

Thanks Patric!

Can you let me know something real quick, was the spam you were getting a lot like the spam I mention in this post? The gibberish spam.

--Matt


Poppoll Poppoll said:
Feb 27th, 2009 at 8:37 pm

Matt,
I have your first mod + the css mod by Fred K.
I want to use your new mod, buth also want to keep the css mod.
How do I do this?
PP


Matt Matt (Admin) said:
Feb 27th, 2009 at 8:52 pm

Hi Pop,

That's easy, just add the hidden (via css) text input into my mathCaptcha funtion and it will work, because the hidden text input logic is all in the checkMathCaptcha() function.

i.e., replace your mathCaptcha function with mine, then ADD the following highlighted to that

$math = '
<p><input type="text" id="your-id" name="some-name" />
<label for="calc">
    * '.l('math_captcha').':
</label><br />';


Poppoll Poppoll said:
Feb 28th, 2009 at 5:53 am

Thanks Matt.


Roie Roie said:
Apr 8th, 2009 at 1:24 pm

many thanks for this excellent mod, been getting tons of spam comments, and since there is no multiple delete function - this was very time consuming and annoying. thanks again!


Sven - Philippe Sven - Philippe said:
Jul 3rd, 2009 at 8:09 am

Terrific robots trap!
Well done again Matt.


toolman toolman said:
Feb 15th, 2010 at 6:18 am

I hate spam too. That is why I loved this modification: D
Good job Matt.



Write a comment

* = required field

:

:

:

:

You may insert urls in plain text, urls will be automatically linkified for trusted users and on seasoned posts only. All first comments are moderated, so use your email if you want to be remembered.


Back to top