Captcha sans image

Qu’est-ce qu’un captcha ? ( "Completely Automated Public Turing test to Tell Computers and Humans Apart".)

C’est donc un test utilisé pour différencier les humains (ou au moins quelque chose d'approchant) des machines.
La plupart des sites utilisent des images plus ou moins lisibles. Elles sont peu utilisables par les utilisateurs malvoyants et pour les aveugles c'est encore pire (le captcha audio n'est pas toujours présent.).
De plus il existe des robots qui savent lire ces images voir par exemple ICI

Tant que les robots chercheront une image par reconnaissance optique de caractères (OCR), il peut être interressant, en tous les cas pour les petits sites, d'utiliser d'autres méthodes. C'est le but de cet article. Ces méthodes peuvent aussi venir en complément d'une image.

frise de séparation mabweb09
Les robots ne savent pas interpréter le CSS on va donc pouvoir cacher un élément en utilisant un style display:none; ou visibility:hidden;. Il sera invisible pour l'utilisateur mais le robot lui le verra.

Il suffit d'ajouter une ligne au formulaire par exemple :

<input type="text" name="surnom" id="surnom" />
                                 

Et de rendre ce champ invisible comme ça :

 
#surnom {
visibility:hidden;
}
                                

Il ne reste plus qu'à tester en PHP si ce champ est rempli :

<?php
if (empty($_POST['surnom'])) {
// Ce n'est pas un robot)
}
else {
// C'est un robot.
}
?>
                                 

frise de séparation mabweb09

Une autre méthode consiste à demander à l'utilisateur de répondre à une question. Pour cela il faut créer une liste de questions/réponses qu'on stockera dans un fichier questions.php par exemple. On crée donc un tableau de 2 éléments, (l'élément [0] contient la question et l'élément [1] contient la réponse).

Extrait d'un fichier de questions (à enrichier évidement)

<?php
$questions = array(

          array(’Résultat en toute lettre de : 1 + 2',’trois’),

          array(’Ecrivez bonjour’,'bonjour’),

          array(’Quel est le 2éme jour de la semaine’,'mardi’),

          array(’Ecrivez zéro’,'zéro’)

          );
?>
                                 

Tout en haut de la page contenant le formulaire (avant le DOCTYPE) il faut inclure le fichier questions.php, prendre une question au hasard et la stocker dans la variable $SESSION pour pouvoir l'utiliser plus tard. Pour prendre une question au hasard on utilise la fonction PHP mt_rand() avec comme paramétres 0 (le premier poste du tableau) et le nombre de poste -1.

Code à inclure

<?php
     include_once(’captcha.php’);
     $_SESSION['question'] = $questions[mt_rand(0,(sizeof($questions)-1))];
?>
                                 

Il faut maintenant rajouter un champ input au formulaire pour cela on récupére la question dans la variable $SESSION.

Code à inclure

Contrôle anti- robots : <?php echo $_SESSION['question'][0]; ?> <
                              input type="text" name="question" value="" /?>
                                 

Il reste maintenant à rajouter le test dans le fichier de vérification du formulaire. Autrement dit si la question existe on la convertit en minuscule et on teste si elle est égale à ce qu'on avait stocké dans la variable $SESSION

Code à inclure

<?php
if(isset($_POST['question']) && strtolower($_POST['question']) == 
               strtolower($_SESSION['question'][1]))
{
          //Traitement du formulaire
}
else 
{
         //Erreur 
}
unset($_SESSION['question']);
?>
                                 

frise de séparation mabweb09

Il existe d'autres méthodes à base de questions. Par exemple une addition ou une soustraction qui change à chaque fois. Tout comme pour la méthode précédente il faut inclure le fichier operations.php dans la page contenant le formulaire. On crée donc une opération au hasard en utilisant le fonction php rand() pour trouver les 2 chiffres et le signe Le signe est déterminé suivant l'élément du tableau(0 ou 1).
Aprés on écrit la question avec echo() et on crée 2 input texte un pour que l'utilisateur puisse répondre et l'autre en chaché (type='hidden') pour stocker les éléments de l'opération séparés par un sous-tiret (_). On aurait pu bien sur le stocker dans la variable $SESSION.

Code à inclure

<?php
function creeroperation()
{	
   $operateur = array("+", "-");
   $c1 = rand(1, 10);
   $op = rand(0, 1);
   $c2 = rand(1, 10);
	
   echo $c1." ".$operateur[$op]." ".$c2." = 
   <input type='text' name='resultat' value='' size='10' maxlength='10'
             style='width:50px;' /><br />";
   echo "<input type='hidden' name='cache'
                   value='".$c1."_".$op."_".$c2."' />";
}
?>
                                 

Il faut maintenant appeler, dans la page du formulaire, la fonction creeroperation() que nous venons d'écrire. Ce qui permettra de creer la question et le champ réponse.

Code à inclure

<p>Contrôle anti- robots :
   Attention le résultat peut-etre négatif (Ex: 3 - 4 tapez : -1)  
 <?php creeroperation(); ?> </p>
                                 

Il reste maintenant à tester la réponse de l'utilisateur. Pour cela on va rajouter une fonction dans notre fichier operation.php. Dans cette fonction on récupère les champs résultat et cache via la variable POST. On teste si le champ réponse est renseigné. Si il y a une réponse on isole les 2 chiffres et le signe de l'opération en utilisant la fonction php explode() (d'où l'utilité du _ ). Après suivant le signe on fait l'opération et on compare le résultat à la réponse de l'utilisateur. Si c'est bon on retourne TRUE autrement on retourne FALSE.

Code à inclure dans operation.php

<?php
function ope_verif()
{
	if((isset($_POST["resultat"]) && isset($_POST["cache"])) 
	{
				{
		$resultat = $_POST["resultat"];
		$cache = $_POST["cache"];
		
            if(strlen($resultat) != 0)
	    {	
		$op = explode("_", $cache);
		
		if(((($op[0] + $op[2]) == $resultat && $op[1] == 0) ||
                    (($op[0] - $op[2]) == $resultat && $op[1] == 1))  )
		{
			return true;
		}
		else
		{
			return false;
		}
            }
            else
            {
		return false;
	    }
	}
	else
	{
		return false;
	}
}
?>
                                 

Enfin il faut ajouter l'appel de cette fonction dans le fichier php de vérification du formulaire.

Code à inclure

<?php
    if (ope_verif() == false)
    {
        // l'addition est fausse
    }
    else
    {
       // c'est bon
    }
?>
                                 

frise de séparation mabweb09

Un dernier exemple un peu différent serait de générer un mot aléatoire et de demander à l'utilisateur de le saisir. Le traitement ressemble à celui ci-dessus (genération des opérations).il faut inclure le fichier mot.php dans la page contenant le formulaire. On crée donc une opération au hasard en utilisant le fonction php rand() pour trouver des consonnes, des voyelles voir même des chiffres.

Code à inclure

<?php
function creermot()
{	
//  le captcha
$captcha = strtoupper(voyelle() . consonne() . consonne() . voyelle() . 
                      consonne() . voyelle()) . rand(0,9);
$mcaptcha = md5($captcha);

   echo "
   <scan><strong> $captcha</strong> </scan>
   <input type='text' name='resultat' value='' size='10' maxlength='10'
             style='width:100px;' /><br />";
   echo "<input type='hidden' name='cache'
                   value='$mcaptcha' />";

}

function consonne()
{
    $consonnes = "bcdfghjklmnpqrstvwxz";
    return $consonnes[rand(0,strlen($consonnes) - 1)];
}
function voyelle()
{
    $voyelles = "aeiouy";
    return $voyelles[rand(0,strlen($voyelles) - 1)];
}
?>
                                 

Il faut maintenant appeler, dans la page du formulaire, la fonction creermot() que nous venons d'écrire. Ce qui permettra de creer la question et le champ réponse.

Code à inclure

<p>Contrôle antirobots : <?php creermot(); ?></p>
                                 

Il reste maintenant à tester la réponse de l'utilisateur. Pour cela on va rajouter une fonction dans notre fichier mot.php.

Code à inclure dans operation.php

<?php
function valider()
{	
    if( (isset($_POST["resultat"]) && isset($_POST["cache"])) )
    {
				
		$cache = $_POST["cache"];
		$mot = $_POST["resultat"];

		
            if(strlen($resultat) != 0)
	    {	
                $resultat = md5($mot);
               if (strtolower($resultat) == strtolower($cache))
               {
                    return true;
               }
               else 
               {
                     return false;
               }
            }
            else
            {
		       return false;
	        }
	}
	else
	{
		return false;
	}
    
}
?>
                                 

Enfin il faut ajouter l'appel de cette fonction dans le fichier php de vérification du formulaire.

Code à inclure

<?php
    if (valider() == false)
    {
        // l'addition est fausse
    }
    else
    {
       // c'est bon
    }
?>
                                 

frise de séparation mabweb09

Voilà un petit résumé de ce qu'il est possible de faire sans image. Il existe bien-sûr d'autres méthodes et il faudra toujours en inventer de nouvelles pour contrer les robots.

Retour à la page principale



image entete

visiteurs

Contact