Problem:
Flash forms are very vulnerable to attacks. Spiders may not be able to easily iterate through your Flash content but they can sure spam your form submission URL. How can you be sure your form was submitted through Flash?

Definition:
A CAPTCHA or Captcha is a type of challenge-response test used in computing to ensure that the response is not generated by a computer.

Solution:
What if we have a user drag a circle onto a box? A spider would have a pretty hard time with that, right? WRONG. While this may be a good filter at the view level it still does not solve our problem. All the hacker would need to do is submit the form correctly one time and use a program like Firebug to sniff the submission URL. They could then completely bypass your view and submit the form as many times as they want.

The only way to ensure the Flash form is being used is to pull the logic out of the view and onto the server. The Flash merely serves up content and never knows what the ‘answer’ is. In this example we will use PHP to generate the image, MySQL to store the key value pairs, and Flash to display the content. This implementation does not require any images to be stored on the server so it NEVER re-uses an existing image. The PHP generates the image on the fly and serves it directly to the Flash application.

Here is a diagram representing the high level information. Blue lines represent Captcha generation and the red lines represent the Captcha verification.

Server Side Captcha in Flash

Server Side Captcha in Flash

Let’s start with the PHP. There are already plenty of PHP scripts out there to generate Captcha. In this example I re-purposed a script called Securimage.

First we need a script that will retrieve the image:

<?php
$flash_id = $_GET['flash_id']; 
include 'securimage.php';
$img = new securimage();
$img->show($flash_id); // alternate use:  $img->show('/path/to/background.jpg');
?>

Next we will need one that verifies the user input with the image:

<?php

$flash_id = $_GET['flash_id']; 
$captcha_text = $_GET['captcha_text'];

if ($flash_id && $captcha_text){
	$con = mysql_connect('localhost', 'DB_USERNAME', 'DB_PASSWORD');
	if (!$con) {
		die('Could not connect: ' . mysql_error());
	}
	mysql_select_db("utils", $con);
	$result = mysql_query("SELECT * FROM captcha WHERE flash_id = '".$flash_id."'");
	$match = 0;
	$valid = 0;
	$answer = "false";
	while($row = mysql_fetch_array($result, MYSQL_ASSOC))
	{
		if($row['valid'] == 1)
		{
			$valid = 1;
			
			if($row['captcha_id'] == $captcha_text){
				$match = 1;
				$answer = "true";
			}
		}
		
	} 
	if($valid == 1){
		mysql_query("UPDATE captcha SET valid = '0' WHERE flash_id = '".$flash_id."'");
		
	}
	echo $answer;
	mysql_close($con);
}
?>

Now that we have the PHP in place we can create the Flash. The display logic is separated from the view so you can re-use this code with any server side script. The Captcha class requires an ID and a URL to the image to display. It has optional styling parameters to match the look and feel of your webpage.

Generating a Captcha in Flash:

// Create a Captcha object
_captcha = new Captcha( );

// Create a unique ID so the server can identify the Flash
var date:Date = new Date();
var id:String = "" + Math.floor(Math.random()*1000) + date.time; 

// Pass in the url along with the ID so the Captcha can load
_captcha.loadCaptcha("http://www.blackcj.com/utils/securimage_show.php?flash_id=" + id, id);

Verifying a Captcha in Flash:

var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, formSuccess, false, 0, true);
var request:URLRequest = new URLRequest("http://www.blackcj.com/utils/check_captcha.php?flash_id=" + _captcha.id + "&captcha_text=" + _text.text);
loader.load(request);

Flash Demo and Source:

Server Side Captcha for Flash

Get Adobe Flash player

(click the image to manually refresh the captcha)

Full source code for Flash & PHP can be found here.

In the source code you will need to replace DB_USERNAME and DB_PASSWORD with your username and password. This example also requires a MySQL database with a table called captcha containing rows flash_id, captcha_id and valid. Valid is used to ensure the Captcha is only submit one time. Since we are always generating a new image there is no reason the Captcha should be allowed to be submitted twice with the same id.

Next Steps:
Additional steps could be taken to prevent robots. Failure rates and number of attempts could be stored for each IP address. No human should ever attempt to re-submit an old Captcha since each time it is randomly generated. The system could block anyone that attempted to re-submit a Captcha.

I would eventually like to make this accessible by integrating audio support. This is a feature of Securimage and would make the utility more versatile.

7 thoughts on “Adding Server Side Captcha to Flash Forms

  1. Now I have a plain Flash Form with Name, Email And a Message filed. I want to add this captcha there how can I do this one. A example source file will be beautiful for this.

    Thanks.

  2. In continuation of my previous post I forgot to mention that the Flash Form I have is In Action Script 2 , now how can I use this captcha in my flash form. Shall be glad if someone help me.

  3. I too am a little confused, how this actually gets implemented onto a flash page. The source files to download are wonderful but do not have a swf files that loads into the html page. I’m having trouble replicating the captcha you have shown here.

  4. The source files included can be imported into Flex / Flash Builder 3 or 4. This software has a 60 day free trial and is available through Adobe. Alternatively you might be able to import the project into Flash Develop. You’ll need to update the code to include your captcha PHP url and re-compile it. I don’t have a FLA or SWF version of this code at this time. Let me know if that helps!

    Thanks,

    Chris

  5. Very interesting article! Has there been any new developments regarding the “Next steps” (i.e. detecting multiple failed attempts and storing IP addressed to prevent robots from using the form)?

    Thank you!

    Eric

Comments are closed.