Formulaire de contact anti-spam

Petit nouveau ! | 3 Messages

28 janv. 2010, 10:42

Bonjour, je suis nouveau sur le forum et complétement novice en php, html et css.
Le soucis c'est qu'il faut quand même que je réalise un site internet pour ma copine. Donc pour le moment j'avance bien grâce à des tutoriels et des cours rapides mais néanmoins je bloque sur un point:

Introduire une question genre "Combien font 4 + 2?" ou mieux une Captcha.

Donc j'ai une page html avec mon formulaire, un fichier php qui effectue tout un tas de vérifications pour voir si ce n'est pas du spam.

Par contre si j'invente une adresse mail avec un @ ca passe et je reçois le message.

J'ai essayé déjà avec des captcha mais je ne sais pas du tout comment m'y prendre: je suppose qu'il faut rajouter du code sur ma page html, mais après est-ce que je dois modifier mon fichier php, en créer un autre....

Bref je suis perdu. Je vous poste mon fichier html + mon fichier php.

Pour le fichier html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Formulaire</title>
 <meta content="text/html; charset=ISO-8859-1"
 http-equiv="content-type" />
 <meta name="content-language" content="fr" />
 <meta name="description" content="formulaire de contact" />
<style type="text/css" media="screen">@import url(design31.css);
</style>
</head>

<body>

<div id="en_tete">
</div>

<div id="onglets">


<ul>

  <li><a href="page1.php"><span>Présentation</span></a></li>

  <li><a href="page2.php"><span>Stages</span></a></li>

  <li><a href="page3.php"><span>Où, quand, comment...?</span></a></li>

  <li id="actif"><span>Me contacter</span></li>

  <li><a href="page5.php"><span>Sites amis</span></a></li>

</ul>

</div>



<div id="corps">
<form id="formulaire" method="post" action="mail.php">
   <label for="nom">Nom</label>
   <input type="text" id="nom" name="nom"/>
   <label for="email">Email</label>
   <input type="text" id="email" name="email"/>
   <label for="requete">Votre demande</label>
   <textarea id="requete" name="requete" rows="6" cols="60">
   </textarea>
   <input type="submit" value="envoyer"/>
 </form>
</div>
<div id="panneau">
</div>

</body>

</html>

Voici mon fichier php:
<?php
$nom=$_POST['nom'];
$email=$_POST['email'];
$requete=$_POST['requete'];
define("DESTINATAIRE",'[email protected]');

$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= "From: $nom <$email>" . "\r\n";

// vérification du bon remplissage du nom
if (empty($nom))
die ("Merci de préciser votre nom.");

// vérification de l'adresse mail
if(!preg_match('#^[a-z0-9.!\#$%&\'*+-/=?^_`{|}~]+@([0-9.]+|([^\s]+\.+[a-z]{2,6}))$#si', $email))
die ('email incorrect, merci de le corriger.');

// vérification de la méthode d'accès au script php
if(!$_SERVER['REQUEST_METHOD'] == "POST")
die("Accès refusé. Vous n’êtes pas autorisé à visiter cette page.");

// vérification que l'email n'est pas adressé en copie ou copie cachée
if (preg_match('#(cc:|bcc:)#i',$headers))
die ("email suspect. Tentative d'envoi annulée.");


//fonction développée par weirdog.com retouchée

function wd_spamScore($body, $author, $words=NULL, $starters=NULL)
{
// score supérieur ou égal à 0 - Le mail a l'air légitime
// score inférieur à 0 - Le mail a l'air d'un spam

// score de départ : 2
$score = 2;
    
// met le contenu du message (la requete = le texte reçu par le textarea) en minuscules
$body = strtolower($body);
    
// compte le nombre de liens figurant dans la requete
$n = max
	(
	array
		(
		substr_count($body, 'http://'),
		substr_count($body, 'href'),
		substr_count($body, 'ftp')
		)
	);

if ($n > 2)
	{
	// si le nombre de liens est supérieur à 2 : -1 point par lien
	$score -= $n;
	}   


// supprime les liens

// html style: <a> <a/>
$body = preg_replace('#\<a\s.+\<\/a\>#', NULL, $body);

// bb style: [url][/url]
$body = preg_replace('#\[url.+\/url\]#', NULL, $body);

// remaining addresses: http://
$body = preg_replace('#http://[^\s]+#', NULL, $body);


//mesure le nombre de caractères restants (hors lien) dans la requete
$l = strlen($body);
    
    
if ($l < 20)
	{
	// si (hormis les liens), le message contient moins de 20 caractères : -1 point
	$score--;
	}
    
// cherche si le message contient des mots clés
$words = array ('levitra', 'viagra', 'casino', 'free sex', 'porn');

foreach ($words as $word)
	{
	$n = substr_count($body, $word);

	if (!$n)
		{
		continue;
		}

	//retire un point par mot clé

	$score -= $n;
	}
    
       
// Si la requete commence par ...
$starters = array ('interesting', 'sorry', 'nice', 'cool', 'hi' );

foreach ($starters as $word)
	{
	$pos = strpos($body, $word . ' ');
	if ($pos === false)
		{
		continue;
		}

	if ($pos > 10)
		{
		continue;
		}

	// retire 10 points

	$score -= 10;

	break;
	}
    
// Si le nom de l'auteur du message contient 'http://'
if (strpos($author, 'http://'))
	{
	// retire 2 points
	$score -= 2;
	}

// analyse la variété du langage

$count = str_word_count($body);

// si le nombre de mots utilisés est inférieur à 10    
if ($count < 10)
	{
	// retire 1 point
	$score --;
	}


// résultat final

return $score;
}

$score = wd_spamScore($requete, $nom);

if ($score >= 0)
	{
	// si le score est positif, le message est envoyé
	mail(DESTINATAIRE, 'mixtures', $requete, $headers);

	print('<br/>Les petites mixtures de Dame Nature vous remercie de votre contribution.<br/><a href="index.php">Retour à l\'accueil</a>');

	unset ($nom, $email, $requete, $headers, $body, $n, $l, $words, $word, $count);
	}

else
	{
	// si le score est négatif, le message n'est pas envoyé (sans que l'auteur en soit informé).
	
	print('<br/>Les petites mixtures de Dame Nature vous remercie de votre votre contribution.<br/><a href="index.php">Retour à l\'accueil</a>');
	unset ($nom, $email, $requete, $body, $n, $l, $words, $word, $count);
	}

?>

Merci d'avance pour votre aide.

Petit nouveau ! | 3 Messages

28 janv. 2010, 11:17

Bon ben j'ai peut être trouvé ici: http://www.6ma.fr/tuto/image+securite+p ... es+php-357

Je teste et vous redis ça.

Petit nouveau ! | 3 Messages

28 janv. 2010, 11:45

Cool ca fonctionne grâce au lien ci-dessus. Le problème c'est qu'il faut taper les lettres en majuscules mais c'est pas très grave.

ViPHP
AB
ViPHP | 5818 Messages

28 janv. 2010, 14:36

Cool ca fonctionne grâce au lien ci-dessus. Le problème c'est qu'il faut taper les lettres en majuscules mais c'est pas très grave.
Tu peux facilement résoudre ce problème :
Remplace
// on vérifie que la code entré est valide
if($_SESSION['code'] != $_POST['verif'])
par
// on vérifie que la code entré est valide
if($_SESSION['code'] != strtoupper ($_POST['verif']))

ViPHP
ViPHP | 5462 Messages

28 janv. 2010, 15:48

pour verifier le mail c'est
filter_var($email, FILTER_VALIDATE_EMAIL);
et un coup de checkdnsrr par dessus

sinon tu peu faire un captcha, simple, avec un MD5 et GD2.