I'm programming a js-based CAPTCHA alternative, and it basically goes as follows.
1. protect.php grabs seven random images from a directory.
2. The first six, which are all pictures of animals, are put in divs which are id'd according to their position on the page. (#image1, #image2, #image3, and so on). The seventh is put inside a target div, and it will say (for the purposes of this exercise) "drop the kitten image here."
2a. One of the first six images is assigned as "correct." The kitten image was #image3 so protect.php stores this information and will proceed only if #image3 was dropped on the target div.
3. jQuery's built-in draggable function is used to allow the user to drag one of the divs onto a target div.
4. Javascript gives the target div a new class which is identical to the id of the dropped image, in this case (if the user did it correctly) .image3.
5. Submit the form.
6. protect.php checks to see if the div has this new class and whether it matches the "correct" image. Since the kitten image was #image3, if the div has the class of .image3 it checks out and the function proceeds.
6a. Otherwise, it says "please try again" and, depending on how difficult of a functionality this would add, will also reload the page and re-randomize the images so that bots have less of a chance of passing the filter by brute force attack.
I need someone who's well-versed with PHP to help me make this happen. I wouldn't be able to correctly complete Step 1. Naturally, if this was copyrighted and became a national phenomenon you would get credit, and all that.
Help incluye create PHP!
-
- Yes sir, no sir, three bags full sir
- Posts: 1561
- Joined: 2008.09.26 (12:33)
- NUMA Profile: http://nmaps.net/user/incluye
- MBTI Type: ENTP
- Location: USofA
- Contact:
Last edited by otters on 2009.08.03 (15:56), edited 1 time in total.

- Lifer
- Posts: 1099
- Joined: 2008.09.26 (21:35)
- NUMA Profile: http://nmaps.net/user/smartalco
- MBTI Type: INTJ
After you have finished loading the page, php can't do anything, it is purely server-side.
(in other words, after step 1, that would all have to be done in JS)
(in other words, after step 1, that would all have to be done in JS)

Tycho: "I don't know why people ever, ever try to stop nerds from doing things. It's really the most incredible waste of time."
Adam Savage: "I reject your reality and substitute my own!"
-
- Yes sir, no sir, three bags full sir
- Posts: 1561
- Joined: 2008.09.26 (12:33)
- NUMA Profile: http://nmaps.net/user/incluye
- MBTI Type: ENTP
- Location: USofA
- Contact:
Fair point. I'll rearrange the steps so it'll make more sense.

-
- Plus (Size) Member
- Posts: 42
- Joined: 2008.09.27 (02:56)
I don't actually have a web server running here, so this won't be tested, but it should be close. You'll want to start by making an array of all the files in your directory (possibly filtered somehow, like only files that end with ".jpg"):
Next up, you'll want to randomly select some files:
Then you just set up your images and have your javascript do its stuff.
The fun part is that you can wrap the whole bit above in an if based on post data, and process the rest in an else:
How to determine the correct index depends on your preference. A simple way is to use some detail about the user (e.g. their IP) to seed the random number generator and then immediately select which index will be correct (you would do that right above where we initialize $verified). A slightly better version would generate a random number in the "$verified==0" case, set it as a cookie, then use it to seed the random number generator:
Code: Select all
$dir = opendir($path_to_dir);
while($ent = readdir($dir)){
//if you want to filter, wrap this line in an appropriate "if"
$contents[] = $ent;
}
closedir($dir);
Code: Select all
$images = array_rand($contents, $num_selections);
//the selected images are still in order; randomize their order:
shuffle($images);
The fun part is that you can wrap the whole bit above in an if based on post data, and process the rest in an else:
Code: Select all
$verified = 0;
if(isset($_POST['some_form_input_name'])){
//check that the correct value was submitted
if($_POST['some_form_input_name'] == $correct_index){
$verified = 1;
}
}
if($verified == 0){
//set up the images and javascript as described above;
//your form input should be referenced in the isset check above
}
else{
//user was verified, so generate the next page here
}
Code: Select all
//...
if(isset($_POST['some_form_input_name'])){
$seed = $_COOKIE['snarfblat'];
srand($seed);
$correct_index = rand(0, $num_displayed_images);
//...
}
if($verified == 0){
$seed = rand();
//make sure that no output comes out before here,
//otherwise setcookie won't work
setcookie("snarfblat", $seed);
srand($seed);
$correct_index = rand(0, $num_displayed_images);
//...
}
//...
- Albany, New York
- Posts: 521
- Joined: 2008.09.28 (02:00)
- MBTI Type: INTJ
- Location: Inner SE Portland, OR
- Contact:
keep in mind that variables in PHP scripts are local in scope to the script's instance. which means that once the page with the form is generated, all the variables used in creating it are destroyed, so when you get the form submitted back you don't know which image was correct (the correct choice variable is no longer set). Handle this by running startsession() at the beginning of the script to get the server tracking sessions, and then storing which image is correct in the $_SESSION array (the $_SESSION array allows you to store data on a per-user basis that is persistent between script instances). Here's how this might look:
There are some performance and security concerns with using $_SESSION, and there are ways you can avoid using it. Those ways involve cryptography and are not completely straightforward, though. One solution would be to put a hidden field in the form with a salted hash of the correct image ID. when the form is submitted the server could then calculate the hash of the imageid+salt and verify that it matches the hash included in the form. As long as the salt is kept local to the server (you may want to make it date-based for security) this is reasonably secure. Here's an example of how this might look:
Code: Select all
startsession()
if(isset($_POST['imageSelected']) {
//they are submitting. check to see if they chose the correct image.
if($_POST['imageSelected'] == $_SESSION['correctImage']) {
//they chose the correct image. give them the page or whatever.
} else {
//they selected the wrong image, error out
}
} else {
//they have not yet recieved the form, send it to them
(select an image)
$_SESSION['correctImage'] = $imageID;
(send the form)
}
Code: Select all
$salt = "aRandomString";
if(isset($_POST['imageSelected']) {
//they are submitting. check to see if they chose the correct image.
if(sha1($_POST['imageSelected'].$salt) == $_POST['correctImageHash']) {
//they chose the correct image. give them the page or whatever.
} else {
//they selected the wrong image, error out
}
} else {
//they have not yet recieved the form, send it to them
(select an image)
$imageHash = sha1($imageID.$salt);
(send the form, with $imageHash in a hidden form element, which I'll call correctImageHash)
}
-- I might be stupid, but that's a risk we're going to have to take. --

Website! Photography! Robots! Facebook!
The latest computers from Japan can also perform magical operations.

Website! Photography! Robots! Facebook!
The latest computers from Japan can also perform magical operations.
Who is online
Users browsing this forum: No registered users and 18 guests