Protéger votre formulaire de contact contre les spammers et hackers
La solution idéale pour être contacté par les utilisateurs de votre site, sans publier votre adresse email, qui deviendrait vite une proie facile pour les spammers, est d’utiliser un formulaire de contact. Il y a d’autres solutions anti spam, mais celle-ci a aussi l’avantage, en plus de paraitre professionnelle, d’offrir un moyen d’être contacté par des visiteurs qui ne peuvent accéder à leur logiciel ou service email lors de leur visite. Toutefois, un formulaire n’est pas complètement invulnérable, à moins de prendre certaines précautions.
La première, est, évidemment, de ne pas publier votre adresse contact dans les champs cachés de votre formulaire, car ça la rends tout aussi vulnérable que si vous la publiez en mode texte. Il ne faut inscrire cette adresse que dans une variable du script qui traite l’envoi du message. Je déconseille aussi vivement l’emploi de logiciels populaires pour traiter l’envoi du formulaire, car ceux-ci deviennent vite la cible des spammers comme le code est public.
Une autre précaution est de vérifier que votre script n’est pas exploité pour envoyer du spam aux autres, ou pire, des virus, à cause d’une vulnérabilité aux attaques par injection. Ce problème pourrait ajouter votre site dans les listes noires (blacklist) du monde comme source de spam et, en plus du risque de voir son compte d’hébergement annulé, vous pourriez ne plus être capable d’envoyer des emails à bien du monde, possiblement un client riche et célèbre.
Voici comment faire:
1 2 3 | if (eregi("MIME-Version:|Content-Type:|Content-Transfer-Encoding:|bcc:|cc:", $email . $message)) { exit("Tentative d'intrusion détectée"); } |
Dans cette instruction, on cherche quelques morceaux de code, tel que MIME-Version: ou bcc:, qui sont souvent « injectés » lors d’un accès direct aux variables de votre script afin de le détourner de sa fonction première pour envoyer du spam aux autres. Mon exemple vérifie $email et $message, mais vous devriez insérer toutes les variables qui sont utilisées dans votre fonction php mail().
Très souvent, les spammers incluent du code html typique dans le message pour promouvoir leurs sites, comme href ou [url]. On peut encore une fois vérifier si le contenu de nos variables n’incluent pas ces indices révélateurs:
1 2 3 | if(eregi("href|\[url\]", $message)) { exit("Nous ne permettons pas de liens html dans les messages."); } |
Certains webmasters vont aussi vérifier si le référant (referer) du navigateur indique bien que l’accès au script provient de la page contenant le formulaire, puisque les spammers accèdent généralement à la page script directement, mais je ne conseille pas vraiment cette méthode parce qu’une bon pourcentage des visiteurs légitimes ne fournissent pas non plus le référant du à la configuration de leur navigateur, de leur logiciel anti-virus ou leur firewall, et pourrait se trouver dans l’impossibilité de vous contacter. Tout de même, je peux publier les grandes lignes de la méthode:
1 2 3 4 5 6 | $referer = $_SERVER["HTTP_REFERER"]; if ($referer) { $domain = parse_url($referer); if ($domain["host"] != "www.example.com") exit("Votre référant ne provient pas de notre site"); } else exit("Nous ne pouvons pas détecter votre référant"); |
En quelques mots, on vérifie le référant, et s’il existe, on compare son nom de domaine au nom de domaine de notre site, dans ce cas www.example.com (insérer le vôtre dans votre code), et si le référant ne provient pas de notre site, ou si nous ne pouvons obtenir de référant, on arrête le script. À utiliser en cas vraiment nécessaire seulement.
Les méthodes prochaines sont un peu plus compliquées, mais fournissent une protection presque totale. Je n’ai jamais eu de problème depuis plusieurs années grâce à celles-ci. En fait, j’ai hésité à les publier parce qu’elles marchent tellement bien, si elles devenaient populaires, les spammers et hackers pourraient trouver une façon des les contourner. Mais bon, les bonnes choses doivent être partagées.
Le principe de la méthode suivante est de vérifier si la valeur d’un champs caché a bien été modifiée par une fonction javascript de validation. En effet, la plupart des logiciels employés par les spammers et les hackers ne sont pas capables (jusqu’à maintenant) d’interpréter Javascript.
En premier lieu, on va remplacer le bouton typique de soumission dans le formulaire:
<input type="submit" value="ENVOYER" />
par un bouton normal qui va utiliser une fonction javascript pour activer la soumission du formulaire:
<input type="button" value="ENVOYER" onclick="if (valider(document.formulaire)) formulaire.submit();" />
La partie formulaire des morceaux document.formulaire et formulaire.submit() devrait être le nom que vous donner à la balise:
<form method="post" action="" name="formulaire">
Ajoutez un champs caché juste après la balise form, comme suit:
<input type="hidden" name="securite" value="" />
Mettez la fonction javascript valider() dans les headers, comme tout code javascript contenu dans une page. Nous allons en profiter pour valider le reste du formulaire afin de s’assurer que tous les champs sont bien remplis, ce qui est une pratique courante et vous épargnera les messages vides envoyés par des utilisateurs débutants qui ne peuvent s’empêcher de cliquer les boutons sur une page avant de savoir à quoi ils servent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <script language="JavaScript" type="text/javascript"> <!-- function valider(formulaire) { var email=formulaire.email.value; var message=formulaire.message.value; formulaire.securite.value = "test_reussi"; if (email == "") { alert("Adresse email manquante"); formulaire.email.focus(); return false; } else if (message=="") { alert("Message manquant"); formulaire.message.focus(); return false; } return true; } //--> </script> |
Ce script n’est pas très compliqué, comme vous pouvez le constater, il vérifie si les champs de notre formulaire sont remplis, et on en profite pour donner la valeur test_reussi (ça pourrait être n’importe quoi d’autre) au champs vide securite.
Ensuite, dans votre script de traitement du formulaire, il suffit de vérifier si la valeur est bel et bien celle que nous lui avons donné avec notre code de validation javascript:
if ($_POST["securite"] != "test_reussi") exit("Tentative d'intrusion détectée");
Et voilà! Votre formulaire de contact devrait être à toute fin pratique invulnérable aux attaques ordinaires.
En fait, si vous avez un petit coté paranoïaque, vous pouvez aussi ajouter une autre fonction, bien que jusqu’ici, vous devriez être franchement barricadé. Comme les attaques sont souvent automatisées par des logiciels qui remplissent tous les champs du formulaire pour passer les test courants de vérification, ou pour injecter leur code malfaisant, on peut aussi ajouter un champs vide caché, et vérifier dans le script si celui-ci a été rempli avec une valeur quelconque, alors qu’elle devrait être restée vide, et rejeter la requête dans ce cas. Exemple:
<input type="hidden" name="vide" value="" />
Ensuite, dans le script:
if ($_POST["vide"] != "") exit("Tentative d'intrusion détectée");
