September 2009
M T W T F S S
« May   Feb »
 123456
78910111213
14151617181920
21222324252627
282930  

A Dynamic, User-Friendly Captcha With Pictures

When people playing Plant Wars train their characters, they frequently encounter a captcha. This is in order to prevent people playing using an auto-refresher or a more sophisticated bot. Interesting trivia: captcha is an acronym for Completely Automated Public Turing test to tell Computers and Humans Apart.

Originally, I had used reCAPTCHA. I felt good about helping digitize books, and it meant I didn’t have to come up with one on my own. My users, however, did not appreciate having to type two words each time. I do still support the project – for things like commenting or registration, it’s great. For Plant Wars, however, the captcha has to come up pretty frequently and people are lazy.

After this, I tied in the integer that is already being stored in the session to prevent refreshing the fight page to create a new captcha. This required the user to do some simple addition and then click the result in a 3 x 3 grid of numbers. It turns out that people don’t like doing math.

At some point, a user had recommended I take a look at this paper by some people over at Google. They implement a captcha by having a slider bar with a randomly rotated image that the user then has to straighten out using the slider bar. This is really cool, and I use the basic idea but simplified yet further. As I am only trying to protect my game from being able to be played by a program, I don’t have to be quite as rigorous.

Captcha

I opted to instead get three “random” images – these are taken from users’ profile pictures – and flip two of them upside-down. Now, instead of typing anything or doing any sort of math, the user simply has to select a picture. It is a relatively secure captcha that is much more user friendly. Now, I’m aware it has its weaknesses – see the Google paper for details on potential problems/vulnerabilities, but here are a few summarized:

  1. These are user-submitted images. People could start uploading pictures that are already upside-down.
  2. Some pictures don’t have an obvious orientation.
  3. A computer could be taught how to tell what’s up/down in many types of pictures (e.g. blue sky indicates that’s the top).

Now all of these are valid issues and obviously reasons for concern, but I’ve concluded this method is sufficient for my purposes. I do plan, however, to add an “I can’t tell head from tail!” link under each picture which, if clicked a sufficient number of times, would flag that picture as unusable for the captcha.

The response from my users has been entirely positive. They were fed up with the old way of doing things, and this is definitely quick and easy.

Technical Details

When the captcha comes up on the training page, it is generated with this function:


function getCaptcha() {
	$_SESSION["pic"] = rand(1,3);
	$string = '<a href="train2.php?pic=1"><img src="captchapic.php?pic=1" border="0" alt="1" width="200" height="200" /></a>';
	$string .= '<a href="train2.php?pic=2"><img src="captchapic.php?pic=2" border="0" alt="2" width="200" height="200" /></a>';
	$string .= '<a href="train2.php?pic=3"><img src="captchapic.php?pic=3" border="0" alt="3" width="200" height="200" /></a>';
	$string .= '<h2>Click the one that is right side up.</h2>';

	return $string;
}

All this does is store a random number between 1 and 3, inclusive, in the session and then insert three pictures with captchapic.php?pic=X as the source.

In captchapic.php, it finds a random profile picture, and if $_GET["pic"] is not $_SESSION["pic"] then it flips the picture upside down.

Here’s the code for that:


        // getRandomPicture() returns the file name for a random profile picture
	$image = getRandomPicture();

	// Unless $_SESSION["pic"] == $_GET["pic"], turn the picture upside down
	if (isset($_GET["pic"])) {
		if ($_GET["pic"] != $_SESSION["pic"]) {
			$degrees = 180;
		} else {
			$degrees = 0;
		}
	} else {
		$degrees = 0;
	}

	// This sets the image type to .jpg but can be changed to png or gif
	header('Content-type: image/jpeg') ;
	// Create the image
	$source = imagecreatefromjpeg($image) ;
	// Rotate the image
	$rotate = imagerotate($source, $degrees, 0) ;
	// Output the image as a jpg
	imagejpeg($rotate) ;

If anyone has an idea for how to improve it further, please let me know! I’m glad for any and all feedback, and while I’m aware that this approach is far from perfect, my users love it.

Update: It has been pointed out that just by randomly selecting a picture, there would be a 33% success rate. This is true and would be reason for concern if this were a public-facing aspect of the site. Players only see this captcha in-game, however. If a user gets the captcha wrong five times in one day, they are automatically jailed. Would I ever replace the conventional captcha for commenting on the blog with it? No. But it works well in particular circumstances where your priorities are to keep your users happy first, and honest second. Also, if you need a lower percentage, you can always just add more pictures.

5 comments to A Dynamic, User-Friendly Captcha With Pictures

  • BJSievers

    The irony that I am still faced with a standard CAPTCHA in order to comment on the blog about a newer, better captcha method amuses me.

  • signal

    The problem is that there’s 0.33 probability of randomly guessing the correct image.
    A bot could just try continuously and achieve 33% of success.

    You should add a check that stops users after N tries

  • admin

    I just updated the post – users do get jailed after 5 tries. Since it’s only an in-game captcha, I have that luxury; I don’t have to defend against the Internet spam bot population as a whole.

  • [...] A Dyna­mic, User-Friendly Captcha With Pic­tu­res « Plant Wars “At some point, a user had recom­men­ded I take a look at this paper by some peo­ple over at Goo­gle. They imple­ment a captcha by having a sli­der bar with a ran­domly rota­ted image that the user then has to straigh­ten out using the sli­der bar. This is really cool, and I use the basic idea but sim­pli­fied yet further. As I am only trying to pro­tect my game from being able to be pla­yed by a pro­gram, I don’t have to be quite as rigo­rous.” Sim­ple and easy captcha. (tags: captcha pro­gram­ming php secu­rity web­de­ve­lop­ment) [...]

  • The problem is that there’s 0.33 probability of randomly guessing the correct image.
    A bot could just try continuously and achieve 33% of success.