| Accueil | FAQ | Statistiques | Divers | Contact |

Anti-spam : comment protéger son blog des spams de commentaires
De nombreux webmasters ne souhaitent pas protéger leurs blogs avec des CAPTCHA ou services de filtrage divers afin de ne pas pénaliser leurs visiteurs. Cependant, il est toujours possible de se protéger des spams de commentaires avec quelques astuces très simples en JavaScript utilisées pour faire la différence entre un robot et un humain, mais aussi de pousser les éventuels spammeurs à se piéger eux-mêmes en les renvoyant sans peine sur un formulaire spécifiquement conçu pour les blacklister ou les renvoyer ailleurs, et bien entendu, en toute transparence pour les visiteurs.
Très simple à installer et relativement efficace : le formulaire se trouve découpé en plusieurs parties JavaScript, chacune d'elle dans une fichier externe faisant référence à l'un ou plusieurs des autres fichiers :
form_01.js :
Aucun spambot n'est en mesure de reconstituer un tel formulaire, sans oublier que vous pourriez rajouter des fonctions totalement obsolètes dans les fichiers JS, voir même encrypter ou masquer les portions de code JS.
Aussi bête que cela puisse paraitre, une autre méthode simple et très efficace que seul un navigateur sera en mesure de reconstituer: pour poster un commentaire, vos visiteurs cliquent sur un lien en JS qui ouvre la fenêtre du formulaire. Le lien, affiché en JS par une fonction affiche_lien() va insérer un autre lien vers la deuxième fonction popup() qui, elle, contient l'URL du formulaire et le code pour ouvrir et centrer la fenêtre.
Fichier JS externe form_01.js :
Un utilisateur normal devra bien taper une portion de texte avant d'envoyer son message. Avec un simple événement comme onKeyUp, lorsqu'il va entrer son nom, une variable cachée recevra une valeur que votre script PHP/ASP ou Perl CGI va vérifier. Si elle n'est pas présente ou incorrecte, le script va rejeter le message posté. Dans cet exemple la valeur incorrecte initiale sera de 1350 et la bonne 893:
Fichier HTML :
Script Perl (ou autre) :
Idem mais en utilisant 3 variables dans un fichier JS externe pour obtenir notre valeur de 893:
Fichier JS externe form_1.js :
D'autres événements comme onMouseOver, onFocus etc feraient aussi bien l'affaire, tout comme onLoad (ou window.load) qui va simplement modifier automatiquement la valeur lors du chargement de la page dans un navigateur :
Il va de soit que le temps entre l'affichage de votre page HTML et l'envoi d'un éventuel commentaire devrait au moins être d'une dizaine de secondes. En postant l'heure exacte de l'affichage au script Perl/ASP/PHP, celui-ci va vérifier le nombre de secondes écoulées. On utilisera l'epoch (nombre de millisecondes/secondes depuis le 1er Janv 1970) avec soit un fichier JS externe, soit SSI (Server Side Includes).
Fichier JS externe + code HTML :
Fichier HTML seul avec SSI :
Script Perl (ou autre) de récupération des données postées :
Sans avoir besoin de faire appel à un système de cryptage, vous pouvez masquer votre formulaire en remplaçant les caractères par leur correspondance décimale avec les fonctions JS charCodeAt() et fromCharCode() et l'insérer tel dans votre page HTML ou mieux, dans un fichier JS externe. Vous pouvez tester ci-dessous:
Cliquez sur "Masquer le code HTML" pour afficher le résultat dans ce cadre :
Vous pouvez télécharger le code JavaScript utilisé dans cet exemple.
La balise <IFRAME> permet de charger une autre page dans votre page HTML principale. Son utilisation est donc très intéressante pour contrer les spams de commentaires en mettant votre formulaire dans un fichier HTML externe :
Page HTML prinicpale :
Bien entendu, rien ne vous empêche de masquer le code d'appel à l'iframe dans votre page HTML avec la méthode décrite dans "Masquer les éléments HTML":
S'il y a une chose que les spammeurs détestent, c'est lorsque l'on décide de jouer avec eux: leur faire perdre leur temps et donc leur argent est la pire des choses qui puisse leur arriver. Il serait vraiment dommage de s'en priver...
Partie HTML:
Le script peut utiliser toute sorte de méthodes pour blacklister comme rajouter l'IP au fichier .htaccess (attention toutefois, le fichier devra être chmodé 0777 ce qui n'est pas très prudent), gérer sa propre base de données d'IP à rejeter et bloquer, ou soit comme ci-dessous tout simplement renvoyer le spambot sur localhost pour lui faire perdre encore un peu plus de son temps.
piege.pl:
Vous disposez d'un serveur dédié ou mutualisé ? Dans ce cas, rien de plus simple : forcez la compression gzip uniquement pour l'affichage de votre formulaire.
Si, comme on vient de le voir, des méthodes très simples peuvent suffir pour éviter les spams de commentaires, d'autres sont à proscrire car totalement inutiles face aux spambots:
D'autres méthodes pourraient être utilisées, notamment le rejet de tout message contenant une URL, puisque ce sera presque toujours le cas des spammeurs. L'utilisation d'AJAX pourrait se montrer très efficace mais en raison de requêtes trop nombreuses votre bande passante pourrait vite en souffrir.
Autres articles : Commentaires (4) De : Courageux Anonyme ben moi qui viens de passer 2 heures a faire une protection par cookies, c'est plutot mal barré De : Rafik C'est marrant, un captcha pour protéger cette page De : spamCle@ner Y a plus de captcha, il est mort De : Rafik Là c'est plus cool en effet. *Message (4 Ko maxi) :
function nom_form(){
document.write("Votre nom: <input type=text name=nom size=20><p>");
}
function close_form(){
document.write("</form>");
}
var monscript='mon_scrip.pl';
form_02.js :
function commentaire_form(){
document.write("Votre commentaire:<br><textarea name=commentaire cols=48 rows=6>");
document.write("</textarea><p>");
}
form_03.js :
function affiche(){
document.write("<form method=post action="+monscript+">");
nom_form();
document.write("Votre email: <input type=text name=email size=20><p>");
commentaire_form();
document.write("<input type=submit value='Poster le message'>")
close_form();
}
Page HTML :
<html>
<head>
<script language="JavaScript" src="form_01.js" type="text/javascript"></script>
<script language="JavaScript" src="form_02.js" type="text/javascript"></script>
<script language="JavaScript" src="form_03.js" type="text/javascript"></script>
</head>
<body>
...
...
<script>affiche();</script>
function popup() {
// hauteur et largeur de la fenêtre en pixels:
var height=400;
var width=400;
// scrollbar (0=non, 1=oui)?
var scroll_bar=0;
// url de la page du formulaire:
var url='http://monsite.tld/monformulaire.html'
var str = "height=" + height + ",innerHeight=" + height;
str += ",width=" + width + ",innerWidth=" + width;
// centre la fenêtre
if (window.screen) {
var ah = screen.availHeight - 30;
var aw = screen.availWidth - 10;
var xc = (aw - width) / 2;
var yc = (ah - height) / 2;
str += ",left=" + xc + ",screenX=" + xc;
str += ",top=" + yc + ",screenY=" + yc;
if (scroll_bar) {str += ",scrollbars=yes";}
else {str += ",scrollbars=no";}
str += ",status=no,location=no,resizable=yes";
}
win = open(url, 'formulaire', str);
}
function affiche_lien(){
document.write('<a href="javascript:popup();">Poster un message</a>');
}
Page HTML :
<html>
<head>
<script language="JavaScript" src="form_01.js" type="text/javascript"></script>
</head>
<body>
...
...
<script>affiche_lien();</script>
...
<form name=formulaire action=mon_script.pl method=post>
<input type=hidden name=evenement value=1350>
...
Nom: <input type=text name=nom size=20 onKeyUp="document.formulaire.evenement.value=893">
...
</form>
#!/usr/bin/perl
use CGI;
$QUERY = new CGI;
$EVENEMENT = $QUERY->param('evenement');
if ($EVENEMENT != 893){
print $QUERY->redirect(-url => "http://fbi.gov");
}
...
...
var topsecret=0;
var soustraire=107;
var valeur=1000;
Fichier HTML :
<form name=formulaire action=mon_script.pl method=post
onSubmit="document.formulaire.evenement.value=topsecret-soustraire;">
<input type=hidden name=evenement value=1350>
...
Votre nom: <input type=text name=nom size=20 onKeyUp="topsecret=valeur">
...
<input type=submit value='Poster le message'>
</form>
<html>
<head></head>
<body onload="document.formulaire.evenement.value=893">
...
<form name=formulaire action=mon_script.pl method=post>
<input type=hidden name=evenement value=1350>
Votre nom: <input type=text name=nom size=20>
<input type=submit value='Poster le message'>
</form>
...
</body>
</html>
function print_epoch(){
var thisdate = new Date();
// getTime() retourne le nombre de MILLISECONDES depuis l'epoch:
var epoch=thisdate.getTime();
document.write("<input type=hidden name=epoch value="+epoch+">");
}
<form name=formulaire action=mon_script.pl method=post>
<script>print_epoch();</script>
...
Votre nom: <input type=text name=nom size=20><p>
...
<input type=submit value='Poster le message'>
</form>
<form name=formulaire action=mon_script.pl method=post>
<!--#config timefmt="%s" -->
<input type=hidden name=epoch value="<!--#echo var="DATE_LOCAL" -->">
...
Votre nom: <input type=text name=nom size=20><p>
...
<input type=submit value='Poster le message'>
</form>
#!/usr/bin/perl
use CGI;
$QUERY = new CGI;
$EPOCH = $QUERY->param('epoch');
if ((!$EPOCH)||($EPOCH!~/^\d{10,13}$/)){goto REDIR}
# ne récupère que les secondes:
$EPOCH=~s/^(\d{10}).*/$1/;
$now=time;
# moins de 10 secondes entre l'affichage de la page et l'envoi des données?
if ($now-$EPOCH<10){
REDIR:
print $QUERY->redirect(-url => "http://fbi.gov");
}
...
<html>
<head></head>
<body>
...
Ceci est mon texte/article...
...
<iframe src="formulaire.html" width=400 height=200 style="border:none;"></iframe>
...
...
</body>
</html>
Page du formulaire (formulaire.html) qui sera chargée par <IFRAME> :
<html>
<head></head>
<body>
<form method=post>
Nom:<input type=text name=nom><p>
Email:<input type=text name=email><p>
Commentaires:<textarea name=comment></textarea><p>
<input type=submit value='Poster'>
</form>
</body>
</html>
Le résultat ci-dessous illustre cet exemple :
<html>
<head></head>
<body>
...
Ceci est mon texte/article...
...
<script>
document.write(String.fromCharCode(60,105,102,114,97,109,101,32,115,114));
document.write(String.fromCharCode(99,61,34,102,111,114,109,117,108,97));
document.write(String.fromCharCode(105,114,101,46,104,116,109,108,34,32));
document.write(String.fromCharCode(119,105,100,116,104,61,52,48,48,32));
document.write(String.fromCharCode(104,101,105,103,104,116,61,50,48,48));
document.write(String.fromCharCode(32,115,116,121,108,101,61,34,98,111));
document.write(String.fromCharCode(114,100,101,114,58,110,111,110,101));
document.write(String.fromCharCode(59,34,62,60,47,105,102,114,97,109,101));
document.write(String.fromCharCode(62));
</script>
...
...
</body>
</html>
Dans cette partie, nous allons reprendre notre premier exemple (multiples fichiers JS externes) mais en encodant l'appel à la fonction affiche() avec fromCharCode(), puis nous allons dans la partie HTML créer un faux formulaire avec de fausses valeurs <INPUT>. Celui-ci sera invisible aux utilisateurs de votre site car caché dans des styles 'DISPLAY:NONE', mais bien visible aux spambots. Quant au vrai formulaire, il ne sera visible qu'aux utilisateurs ayant un navigateur digne de ce nom. En postant les données via ce formulaire bidon, le spammeur va tout simplement se piéger lui-même et sera blacklisté ou redirigé ailleurs:
<html>
<head>
<script language="JavaScript" src="form_01.js" type="text/javascript"></script>
<script language="JavaScript" src="form_02.js" type="text/javascript"></script>
<script language="JavaScript" src="form_03.js" type="text/javascript"></script>
</head>
<body>
...
<!-- affiche le vrai formulaire en encodant "<script>affiche();</script>" -->
<script>
document.write(String.fromCharCode(60,115,99,114,105,112,116,62,97,102,102,105,99));
document.write(String.fromCharCode(104,101,40,41,59,60,47,115,99,114,105,112,116,62));
</script>
..
..
<!-- formulaire pour les spambots -->
<div style="display:none;">
<form method=post action=piege.pl>
Nom:<input type=text name=nom>
Email:<input type=text name=email>
Commentaires:<textarea name=comment></textarea>
<input type=submit value='Poster'>
</form>
</div>
#!/usr/bin/perl
use CGI;
$QUERY = new CGI;
print $QUERY->redirect(-url => "http://127.0.0.1");
exit;
Ouvrez votre fichier apache2.conf et entrez la ligne suivante :
SetEnvIf Request_URI contac.html force-gzip
Remplacez contac.html par le nom de la page de votre formulaire puis relancez apache. Comme son nom l'indique, la variable d'environnement force-gzip a pour effet d'envoyer systématiquement le contenu de la page au format compressé gzip, y compris si le destinataire ne le prend pas en charge, et donc de la rendre totalement illisible aux simples bots/scripts des spammeurs.
Voici un aperçu de ce qu'ils obtiendront :
�T��W��.�;Jt@#f�� ��\̷
�F��>}�[]�+�B7�������7��j�1f��4��0,�"���h.;�n�7���QYEJwEP�VYf
�N w�����ؘ���
ק���®.▒8ªìW._F 5+Ò┬§Õç KÎý®æé
ÆÕ¢÷ù┘#ðê«ô²▒SÊÐ_éÝ▒à¹=Ì ùàÃç·3≠MVê┐Ø
° $¶┘¿§Ù┌ñÕ5R≤°┼« ½8Ð"␍┼┐6Ù┌⎻�=-�o����A�T
�J_�C��Ln���N���ku@��^
�ÆƗ1�
Ŕ�ڑM�ٔ��я?�i'Ӆ�n8�ɲ����ޞ��F!��g�]�0� ��K�
;cv�>���
!{(��×%�98h�Y|�q�xx>
���a��.�;,mw����P?p\wڠR�s �αb;����Y
|���nѠ ��$1������8ڰ�CA��2�N���N���wS�'�
t�#�3@�[(��ij���u��M��D:�}9X���|ĤiÒÔ┘æGIµB%:◆
Aù¹┐┴┐ó#ÆO+µÞîF│è§ZëS¾≤/=ºå
+ï"Â\¹ÑÞY¯éÛAçÁ
ô£4V3þ×ÕøC ªÖÚ
=¯Y"µOâX%ûⰈ萁म惄⑂”ဲཀॷ⡒✻鬃錪悤乇灀漬蚈刖瑺眑㈌潺К惝潯ⰶ
鱐ऻ梂䰁úõAÞÌ: ÕËðISô│[G9©Ý½ÝÙ^─8 ┴┐£Ò
;Y>óáLëÔìÞ^CÆO:≤>Ú┴V┌òÚ≥ÍGÃKN
ïéä⎻!9,Ťó·õáÚ≥;ó┼ë4=±Ô7ö²!␌;üB┐^â÷V]
°ëÖª␊ÁBü¹
¢^¾ÃPT7┐÷ó£
/ñÅF¤»ò≠S0H␍B¡ðÞø\┴
õâ└
����Jt�DO����k'i���;�[{�3�����zwk�b]��
"`xRA!c�uӱuúG:úÉL┴ì6(±$H^ P
-vérification du referer (HTTP_REFERER): les spammeurs peuvent forger celui-ci et vous faire croire qu'ils viennent de n'importe quel endroit, y compris de votre page de commentaires.
-les cookies: un spambot peut très facilement accepter tous les cookies que vous lui donnerez et vous les retourner à chaque fois que vous les lui demanderez (il suffit juste de 5 ou 6 lignes de code pour le faire).
-bloquer les IP à long terme: si vous bloquez les IP, ne les bloquez pas plus de quelques heures car les spammeurs utilisent des proxies et vous risqueriez de vous retrouver rapidement avec de très longues listes d'IP ne servant pas à grand chose sauf à ralentir terriblement votre site car le fichier .htaccess et des modules comme mod_rewrite ne sont pas réputés pour leur rapidité et ne sont pas fait pour gérer des centaines de lignes de code.
Les meilleures méthodes ne sont pas celles qui sont compliquées mais celles qui sont personnalisées, sans oublier l'alternance. Votre formulaire étant probablement créé par un script, il est facile lors de chaque requête d'alterner les différentes possibilités vues ci-dessus ainsi que d'autres aussi simples et efficaces et surtout sans aucune contrainte pour vos utilisateurs si vous ne souhaitez pas les obliger à recopier un CAPTCHA ou bien devoir attendre une validation/modération de leurs messages.

Le : 2-Oct-2007 à 23:42:54
Le : 23-Oct-2007 à 22:20:47
Le : 24-Oct-2007 à 13:32:48
En plus, il n'était pas beau.
Le : 24-Oct-2007 à 18:36:58
Good work.
Poster un commentaire
Nom :