Sécurisez vos formulaires contre les spams

police.png

Vous avez un banal site vitrine , un livre d'or ou autres formulaires de contact / commentaires , sans protection , même minime , vous allez rapidement voir apparaître des messages non sollicités , qui peuvent même parfois se révéler dangereux .
Cet article vise à donner une solution ( parmi beaucoup d'autres ) pour éviter ce genre de désagrément , et sans le moindre captcha .
Nous allons prendre un simple formulaire de contact pour l'exemple

Le code de base , sans aucune protection

Le formulaire

<form name="contact" method="POST" action="send.php" >
    
    <table>
        <tr>
            <td>
                Pseudo :
            </td>
            <td>
                <input type="text" name="pseudo" >
            </td>
        </tr>
        
        <tr>
            <td>
                Mail :
            </td>
            <td>
                <input type="text" name="email" >
            </td>
        </tr>
        
        <tr>
            <td>
                Message :
            </td>
            <td>
                <textarea name="message" ></textarea>
            </td>
        </tr>
        
        <tr>
            <td>
                <input type="submit" name="envoyer" value="envoyer" />
            </td>
        </tr>
    </table>
    
</form>

Envoi du mail

<?php
/*
 * send.php
 * 
 */

//récupération et filtrage des données
$tData = filter_form( $_POST, "utf-8" );

//envoie du mail 
sendMail( $tdata );

?>

Voilà , quoi de plus simple .. mais quoi de plus vulnérable par le spam !!!!
Note: je ne traiterais pas ici des fonctions filter_form() et sendMail() , n'étant que des fonctions fictives pour éclaircir au maximum le code .

Protection 1 : rendre le formulaire unique

Et oui ce n'est pas parce que le formulaire est là qu'une personne malveillante doit y passer pour envoyer le mail , ce qui permet aux "pirates" de forger des requêtes , envoyé soit par une de leurs victimes , un robots ou autres méthodes détournées .

Pour rendre le formulaire unique , nous allons lui ajouter un jeton , qui sera changeant constamment , ainsi avant l'expédition du mail , l'on vérifie que le jeton est là et valide
Voilà le formulaire modifié

<form name="contact" method="POST" action="send.php" >
    
    <table>
        <tr>
            <td>
                Pseudo :
            </td>
            <td>
                <input type="text" name="pseudo" >
            </td>
        </tr>
        
        <tr>
            <td>
                Mail :
            </td>
            <td>
                <input type="text" name="email" >
            </td>
        </tr>
        
        <tr>
            <td>
                Message :
            </td>
            <td>
                <textarea name="message" ></textarea>
            </td>
        </tr>
        
        <tr>
            <td>
                <input type="submit" name="envoyer" value="envoyer" />
                
                <input type="hidden" name="jeton" value="<?php echo  md5('graindesel'.date('Y-m-d h:i:00'));?>" />
                
            </td>
        </tr>
    </table>
    
</form>

Et au niveau de send.php , il nous suffit d'ajouter la vérification du jeton de la façon suivante :

<?php
/*
 * send.php
 *
 */

//récupération et filtrage des données
$tData = filter_form($_POST,"utf-8");

//cree un tableau de 0 à 10
$validite = range(0, 10) ;
//initialise le resultat
$valide = false ;
//vérifie le jeton
foreach($validite as $v) {
        $valide |= ( $_POST['jeton'] == md5('graindesel'.date('Y-m-d h:i:00', mktime() - $v * 60)));
}

if( !$valide ){
	//redirection vers une page d'erreur
}else{
        //envoie du mail
        sendMail($tdata);
}

?>

Contrairement au formulaire initial cette fois le "pirate" est obligé de passer par le formulaire pour envoyer le mail , le jeton étant valide 11 minutes , un internaute devra remplir et envoyer ce formulaire en maximum 11 minutes , ce qui est largement faisable . :-)

Protection 2 : filtrage anti-spam

La protection du formulaire unique permet déjà de réduire de façon notable l'envoie de spam via cette page , maintenant certains réussirons toujours à passer outre , rien de bien compliqué à celà .
La derniére solution avant expédition , est d'utiliser un service enti-spam tel que akismet

Akismet est un Web-service à qui nous allons envoyer les données du formulaire , en réponse nous arons un simple booléen qui nous indiquera si oui ou non le message semble être un spam .

Enregistrement Akismet

Il vous faut une clef ( gratuite ) , pour celà allez vous enregistrer sur le site d'akismet

Utilisation akismet

Le site vous propose de nombreux plugins déjà prêts pour des applications comme Dotclear , Wordpress , punBB ect ... Mais aussi des "class" php pour des scripts perso comme le notre .

Nous allons donc télécharger la classe proposé par le site achingbrain.net

L'utilisation est trés simple, dézipez l'archive afin de rendre la classe accessible par votre serveur web ... ( je vais la mettre au même endroit que send.php pour l'exemple )

et voilà la modification de send.php pour utiliser ce service :

<?php
/*
 * send.php
 *
 */

//récupération et filtrage des données
$tData = filter_form($_POST,"utf-8");

//cree un tableau de 0 à 10
$validite = range(0, 10) ;
//initialise le resultat
$valide = false ;
//vérifie le jeton
foreach($validite as $v) {
        $valide |= ( $_POST['jeton'] == md5('graindesel'.date('Y-m-d h:i:00', mktime() + $v * 60)));
}

if( !$valide ){
	//redirection vers une page d'erreur
}else{
    
    //Test AKISMET
    $APIKey = 'aoeu1aoue';
    $MyURL = 'http://www.lindev.fr/contact/';

    $akismet = new Akismet($MyURL ,$APIKey);
    $akismet->setCommentAuthor( $tdata['pseudo'] );
    $akismet->setCommentAuthorEmail( $tdata['email'] );
    $akismet->setCommentContent( $tdata['message'] );
    $akismet->setPermalink( $MyURL );

    if($akismet->isCommentSpam()){
        //redirection vers une page d'erreur
    }else{
        //envoie du mail
        sendMail($tdata);
    }
}

?>

Cette fois non seulement l'utilisateur doit passer par le formulaire , mais en plus le message sera vérifié par un service anti-spam , ce qui vous permet d'éliminer plus de 90% des mails/messages non sollicités qui peuvent provenir de ce genre de formulaire .
Et ce sans captcha :-)

Autre barrière:

Il existe encore une autre barrière , si vous êtes encore embêté , l'interrogation de listes rbls , qui vous indique si l'adresse ip du client qui remplis votre formulaire est listé comme spammeur ou non ..
Juste pour information , en voici une pour exemple :

http://bsb.spamlookup.net/

A bientot , Ch.