View Full Version : PHP Captcha revisited

May 6th, 2006, 03:16 PM
Hi, an alternate type of Captcha test ...as opposed to trying to decipher the weird fonts ... count the little piggies :)

(and no sadly it is not accessible though hints on how to make it so would be much appreciated)

you can grab sample code and images here (http://www.firepages.com.au/public/captcha_test.zip)

Sample Usage

session_start(); /*yes we need a session*/
include_once './captcha/captcha.php';
/*the check is best done as a static call*/
echo 'false';
echo 'true';
/* start the captcha using
/home/www/captcha for the image directory
using 3 unique images
showing a total of 6 images for user to count from
and ask 2 questions
$yaks=new captcha('/home/www/captcha',3,6,2);
echo $yaks->get_captcha();

captcha.php class

<?php /*alternative captcha class :: firepages.com.au*/
DEFINE('CAPTCHA_TIMEOUT',3600);//an hour, way too much ?
DEFINE('CIF','jpg'); //CaptchaImageFormat
DEFINE('CIM','image/jpeg'); // MimeType
DEFINE('CONVERT','convert'); //Path to imagemagick convert library

class captcha{
var $search = array('{Q_WHAT}','{Q_WHAT_IMG}','{Q_INAME}');
var $im_num; #how many images to use from repository
var $complex; #how many images to show altogether
var $img_path; #path to image repository

function captcha($img_path,$im_num=3,$complex=6,$num_questions=3){
/*image path relative to calling HTML*/
$this->rel = str_replace(array(getcwd(),basename(__FILE__)),'',__FILE__);

function set_session($hash,$answers){
$_SESSION['fpa_captcha']['start'] = mktime();
$_SESSION['fpa_captcha']['hash'] = $hash;
$_SESSION['fpa_captcha']['a'] = $answers;

function start_captcha(){
while($x < $this->complex){
$str[] = $this->ims[$r];
$this->ims_used = $ims_used;
$str = implode(' ',$str);
$hash = MD5($str);
exec(CONVERT." $str +append {$this->img_path}/out/{$hash}.".CIF);
return '<img src=".'.$this->rel.'out.php?r='.mktime().'" />';

function get_questions($format=''){
$format = empty($format) ? #default format if not passed
'How many {Q_WHAT}\'s ? &nbsp; <input type="text" name="{Q_INAME}" value="" /><br />' :
$format ;
foreach($arr as $im){
$str[] = str_replace($this->search,$replace,$format);
return implode("\n",$str);

optional call to keep your code neat, wraps start_captcha and get_questions according to $format
$format must include {IMG} and {QUESTIONS} replacers !!
function get_captcha($format="{IMG}<br />\n{QUESTIONS}", $q_format=''){
return str_replace(

/*validation can be static & MUST be called before start_captcha() if form is posting to itself !!*/
function validate($req){
$time=mktime();$valtime = $_SESSION['fpa_captcha']['start'];
if(empty($_SESSION['fpa_captcha']) || (($time - $valtime) > CAPTCHA_TIMEOUT)){
return false;
foreach($_SESSION['fpa_captcha']['q'] as $q){
if( $req[MD5($_SESSION['fpa_captcha']['hash'].$q)] != $_SESSION['fpa_captcha']['a'][$q] ){
return false;
return true;

out.php (for serving the capture image)

echo file_get_contents("out/{$_SESSION['fpa_captcha']['hash']}.{$_SESSION['fpa_captcha']['CIF']}");

Updates and more examples can be found here (http://www.firepages.com.au/captcha.htm)

May 6th, 2006, 06:12 PM
I don't see how this can be made accessible, without adding alt text to the images, but then if you do that it's trivial to crack programatically.

The only form of test that I'm aware of which is accessible is Eric Meyer's "gatekeeper" plugin for wordpress - http://www.meyerweb.com/eric/tools/wordpress/wp-gatekeeper.html

It basically ask random questions like "what color is an orange", or "how many is a dozen", and its crackability is how many different questions there are, so if someone does break it you can just add more questions, and each site you use it on can have a different, unique, set of questions.

May 6th, 2006, 06:27 PM
It is too easy to crack. I've written something that gives the correct number of those images and would probably work with any number of images.

May 7th, 2006, 02:45 AM
I don't see how this can be made accessible, without adding alt text to the images, but then if you do that it's trivial to crack programatically.

absolut , I am thinking along the lines of audio with the same basic premise , dynamically tack together several random audio files into one file, play it.. then ask the user .. `how many pigs did you hear` ? etc.. the only way I can do this at the moment is via flash files & I dont know how thats all gonna tie in with accessibility... any ideas appreciated.

It is too easy to crack. I've written something that gives the correct number of those images and would probably work with any number of images

how ? dont you need to do some image processing to work that out (since the capture image is a randomly named single image) , ok I appreciate that that's doable but hardly easy, most OCR cracks are text-based.

....unless you are working it out from the form input names & session id's ? I thought that the session based attacks should fail (not that I have tried it yet) please tell :) even though its just for captcha I would still like to secure it if possible.

I mean its easy enough to brute force, 2 questions * 6 images = 64 attempts (I think) but there are other ways to spot brute-forcing (though not reliably)

PS if nothing else it solved the spamming issue on the form I originally created it for (for now at least) so something is obviously better than nothing :)

May 7th, 2006, 10:05 AM
First of all you give the images used in that image in the questions.
The cpatcha image has the images neatly lined up therefore checking if parts of the image are like one of those in the questions it is easy.
even without the images in the questions you could count the number of different images. I'd suggest that the images to build up the captcha were different sizes, not aligned, tilted and the image it self deformed.

BTW I've seen a php generated audio captcha, though it also seemed easy to crack.

May 7th, 2006, 10:59 AM
ok what about this... if the images in the captcha image were randomly reversed, rotated and possibly re-coloured ? I dont want to distort them too much... but would that make it a bit harder ?, lol OK I know it would ... but how far do you go ?
The problem with the best current Captcha images is that if they are too hard for OCR then they are often too hard for humans to read as well :)

BTW using the images in the questions is optional you can just use the text but then you have the language issue.

I think any such system is crackable... its a case of just making it harder for passing bots to automate attacks.

May 7th, 2006, 11:28 AM
Oh well security is not exactly a friend of accessability... and it is true that ultimate security is no accessability :)

ralph l mayo
May 8th, 2006, 03:38 AM
$_SESSION['fpa_captcha']['a'] = $answers;


If the client accepts cookies they get plaintext answers?

May 8th, 2006, 04:16 AM
no they get a cookie containing a sessionID

ralph l mayo
May 8th, 2006, 04:34 AM
oh, ok.

May 8th, 2006, 11:42 PM
An audio captcha still isn't accessible - what if you're blind and deaf? Or what if you don't have an audio plugin, or no soundcard or speakers?

Clearly it's better than just using a visual one, but not using one at all is the only way to be properly accessible. Not unless it's something that doesn't depend on output mode.

Mind you, even the Gatekeeper isn't completely accessible - it requires an amount of knowledge that might make it unuseable by young children or someone with severe learning difficulties.

Perhaps it could be simplified by a structure of questions with multiple-choices, only one of which could possibly be correct, such as, for instance "which of these is not a president?" where the possible answers are "president bush", "president mbeki" or "king husssein".

My 3-year-old neice could get that right :)

May 28th, 2006, 02:39 PM
I saw an excellent captcha on a site earlier. Perhaps something like this would be better (I agree with marek_mar that your current implementation is far from uncrackable).

May 28th, 2006, 03:38 PM
Pretty neat, but yeah a bit easy to evade. Cool all the same.

I think logic tests are a good way to do this sort of thing too.

For example, questions that anybody (should) be able to answer like "What color is grass?", "What is ten times two?"

Just change the questions once a month or so.

No captcha is the be all and end all to security of an application though, it's just yet another obstacle to get past.