Page 1 sur 1

Formulaire de contact sécurisé

Posté : 05 juil. 2014, 23:28
par StryceKK
Bonjour à tous.

J'essaie actuellement de créer nu formulaire de contact sécurisé, mais l'envoie ne se fait pas et je n'ai pas d'erreur PHP apparente.
<?php
 
ini_set('display_errors', '1');
error_reporting(E_ALL);
 
    //If the form is submitted
    if(isset($_POST['btn-submit-form-contact'])) {
 
        //Check to make sure sure that a valid email address is submitted
        if(trim($_POST['email']) == '')  {
            $hasError = true;
        } else if (!filter_var( trim($_POST['email'], FILTER_VALIDATE_EMAIL ))) {
            $hasError = true;
        } else {
            $email = trim($_POST['email']);
        }
 
        //Check to make sure that the subject field is not empty
        if(trim($_POST['subject']) == '') {
            $hasError = true;
        } else {
            $subject = trim($_POST['subject']);
        }
 
        //Check to make sure that the second name field is not empty
        if(trim($_POST['contact_second_name']) == '') {
            $hasError = true;
        } else {
            $second_name = trim($_POST['contact_second_name']);
        }
 
        //Check to make sure that the first name field is not empty
        if(trim($_POST['contact_first_name']) == '') {
            $hasError = true;
        } else {
            $first_name = trim($_POST['contact_first_name']);
        }
 
        //Check to make sure comments were entered
        if(trim($_POST['message']) == '') {
            $hasError = true;
        } else {
            if(function_exists('stripslashes')) {
                $comments = stripslashes(trim($_POST['message']));
            } else {
                $comments = trim($_POST['message']);
            }
        }
 
    //If there is no error, send the email
    if(!isset($hasError)) {
        $mail = '[email protected]'; // Déclaration de l'adresse de destination.
        if (!preg_match("#^[a-z0-9._-]+@(hotmail|live|msn).[a-z]{2,4}$#", $mail)) // On filtre les serveurs qui présentent des bogues.
        {
            $passage_ligne = "\r\n";
        }
        else
        {
            $passage_ligne = "\n";
        }
 
        //Déclaration des messages au format texte et au format HTML.
        $message_html = "<html><head></head><body>".$_POST['message']."</body></html>";
          
        //Création de la boundary
        $boundary = "-----=".md5(rand());
          
        //Définition du sujet.
        $sujet = $_POST['subject'];
        //
          
        //Création du header de l'e-mail.
        $header = "From: \"".$_POST['contact_first_name'] .$_POST['contact_second_name']."\"<".$email.">".$passage_ligne;
        $header.= "Reply-to: \"".$_POST['contact_first_name'] .$_POST['contact_second_name']."\"<".$email.">".$passage_ligne;
        $header.= "MIME-Version: 1.0".$passage_ligne;
        $header.= "X-Priority: 3".$passage_ligne;
        $header.= "X-Confirm-Reading-To: ".$email;
        $header.= "Content-Type: text/html; charset=\"utf8\"".$passage_ligne."boundary=\"$boundary\"";
        //
   
        //Création du message.
        $message = $message_html;
        //
 
        //Ajout du message au format HTML
        $message.= $passage_ligne.$message_html.$passage_ligne;
        $message.= $passage_ligne."--".$boundary."--".$passage_ligne;
        $message.= $passage_ligne."--".$boundary."--".$passage_ligne;
        //
         
        /* Expression régulière permettant de vérifier qu'aucun en-tête n'est inséré dans nos champs */
        $regex_head = '/[\n\r]/';  
          
        /* On vérifie qu'il n'y a aucun header dans les champs */
        if (preg_match($regex_head, $email) 
            || preg_match($regex_head, $_POST['contact_first_name']) 
            || preg_match($regex_head, $_POST['contact_second_name'])
            || preg_match($regex_head, $_POST['subject'])
            || preg_match($regex_head, $_POST['message']))
        {  
            $alert = '<span class="help-block">En-têtes interdites dans les champs du formulaire</span>'; 
        }
        else
        {
            /* Si le formulaire n'est pas posté de notre site on renvoie vers la page d'accueil */
            if ($_SERVER['HTTP_REFERER'] != 'http://www.lucasfrugier.fr/?page=contact.php')
            {  
                header('Location: http://www.lucasfrugier.fr/'); 
            } 
            else
            {  
                //Envoi de l'e-mail.
                mail($mail,$sujet,$header,$message);
            }
        }   
          
        /* On affiche l'erreur s'il y en a une */
        if (!empty($alert))
        {
            echo $alert;
        } 
    }
}
?>
Si quelqu'un pouvait m'éclaircir ce ne serait pas de refus.
Cordialement.

Re: Formulaire de contact sécurisé

Posté : 06 juil. 2014, 09:03
par Elie
Peux-tu mettre la page du formulaire que je fasse un test plus rapidement ?

Re: Formulaire de contact sécurisé

Posté : 06 juil. 2014, 09:12
par xTG
if(!isset($hasError)) {
Ce if n'a pas de else et donc pas d'affichage d'erreur dans ce cas là. ;)

Re: Formulaire de contact sécurisé

Posté : 06 juil. 2014, 11:22
par sirakawa
if(!isset($hasError)) {
Ce if n'a pas de else et donc pas d'affichage d'erreur dans ce cas là. ;)
Ausi est-il prudent de créer la structure complète du if dès le début, de le commenter (-ce sont des assertions sur lesquelles on peut faire des opérations logiques de vérification) , voire de numéroter les parties pour être sûr qu'il est complet:
if (c) //le camion est chargé
{//1
if (d) // le camion est chargé et le diesel fonctionne
{//2
}
else// le camion est chargé et le diesel ne fonctionne pas...
{
}//2
}
else //le camion n'est pas chargé
{
}//1

Re: Formulaire de contact sécurisé

Posté : 06 juil. 2014, 15:19
par Strycekk
Voici pour le formulaire :
<section id="contact" class="wrapper style3 container special-alt">
	<form class="form-horizontal" role="form" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" name="contactform" id="contactform" accept-charset="UTF-8">
		<div class="form-group">
			<div class="col-md-8">	
				<input type="email" class="form-control" name="email" id="email" value="" role="input" aria-required="true" placeholder="Email" />
			</div>
		</div>	
		<div class="form-group">
			<div class="col-md-8">		
				<input type="text" class="form-control" name="subject" id="subject" value="" role="input" aria-required="true" placeholder="Objet" />
			</div>
		</div>		
		<div class="form-group">
			<div class="col-md-4 col-md-offset-0">		
				<input type="text" class="form-control" name="contact_second_name" id="contact_second_name" value="" role="input" aria-required="true" placeholder="Nom" />
			</div>
			<div class="col-md-4 col-md-offset-0">		
				<input type="text" class="form-control" name="contact_first_name" id="contact_first_name" value="" role="input" aria-required="true" placeholder="Prénom" />
			</div>
		</div>		
		<div class="form-group">
			<div class="col-sm-8">		
				<textarea rows="8" class="form-control" name="message" id="message" role="textbox" aria-required="true" placeholder="Votre message"></textarea>
			</div>
		</div>
		<div class="form-group">
			<div class="col-xs-1">
				<input type="submit" class="btn btn-primary" value="Envoyer" name="btn-submit-form-contact" id="btn-submit-form-contact" role="button" />
				</div>  	
			<div class="col-xs-1">
				<input type="reset" class="btn btn-warning" value="Effacer" name="btn-reset-form-contact" id="btn-reset-form-contact" role="button" />
			</div>
		</div>
	</form>
</section>

Re: Formulaire de contact sécurisé

Posté : 06 juil. 2014, 19:49
par Elie
Personne n'a remarqué que $message et $header sont inversés ?
mail($mail,$sujet,$header,$message);
bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )

Re: Formulaire de contact sécurisé

Posté : 06 juil. 2014, 20:58
par Strycekk
Merci. Le mail s'envoie maintenant mais le navigateur interprète pas mes balises dans mon message ..

Re: Formulaire de contact sécurisé

Posté : 08 juil. 2014, 15:07
par ynx
Salut,

Pour que tes balises html soient interprétées, il faut spécifier le type mime de ton mail.
C'est bien ce que tu as fait en déclarant les entêtes http du mail (variable $headers), mais tes entêtes doivent se terminer par un retour à la ligne.

Actuellement tes entêtes http ne sont pas prises en compte, corrige les en ajoutant le retour à la ligne (regarde le deuxième exemple de la doc : http://www.php.net/manual/fr/function.m ... ample-3499).

Edit : tu as bien un saut de ligne avec la variable $passage_ligne, mais pas sur l'avant dernière entêtes. Pour vérifier si tes entêtes sont biens présentes, regarde le code source de ton mail (raccourci Ctrl+U sous Thunderbird)

Bonne journée

Re: Formulaire de contact sécurisé

Posté : 09 juil. 2014, 18:27
par Strycekk
Merci beaucoup, ça fonctionne.
Pensez vous que mon formulaire de contact est suffisamment sécurisé ?

Re: Formulaire de contact sécurisé

Posté : 10 juil. 2014, 12:24
par ynx
Non, pas suffisamment.

Maintenant que ton mail est bien interprété en html, il faut éviter les failles xss (http://fr.wikipedia.org/wiki/Cross-site_scripting)
Pour s'en protéger, le plus simple est d'appliquer la fonction htmlentities() sur les données que tu affiches en html, ici le message (encodage à vérifier si ton fichier est bien en utf-8) :
//Déclaration des messages au format texte et au format HTML.
$message_html = "<html><head></head><body>" . htmlentities($_POST['message'], ENT_QUOTES, 'UTF-8') . "</body></html>";
(Tu avais prévu une variable $comment mais celle-ci n'est jamais utilisé. Néanmoins préfère la fonction htmlentities à la place de stripslashes pour éviter les failles xss).

Contrôler le Referer est aussi une bonne technique pour vérifier que le message vient bien du formulaire de ton site, mais l'utilisateur peut facilement modifier cette entête. Tu pourrais alors ajouter un jeton de sécurité pour renforcer ce point, mais la protection contre les failles xss rend déjà ton formulaire suffisamment sécurisé (le minimum requis).

Bonne journée

Re: Formulaire de contact sécurisé

Posté : 10 juil. 2014, 19:03
par Strycekk
Merci beaucoup. Par contre je viens de remarquer quelque chose d'assez étrange, quand je mets des espaces dans ma variable subject, qui se réfère au champs objet, le mail ne s'envoie pas et a contrario quand je n'en mets pas, le mail s'envoie, et ça fait ça seulement sur ce champs..

Je reposte mon code pour ceux qui veulent :
<?php

ini_set('display_errors', '1');
error_reporting(E_ALL);

	//If the form is submitted
	if(isset($_POST['btn-submit-form-contact'])) {

		//Check to make sure sure that a valid email address is submitted
		if(trim($_POST['email']) == '')  {
			$hasError = true;
		} else if (!filter_var( trim($_POST['email'], FILTER_VALIDATE_EMAIL ))) {
			$hasError = true;
		} else {
			$email = trim($_POST['email']);
		}

		//Check to make sure that the subject field is not empty
		if(trim($_POST['subject']) == '') {
			$hasError = true;
		} else {
			$subject = trim($_POST['subject']);
		}

		//Check to make sure that the second name field is not empty
		if(trim($_POST['contact_second_name']) == '') {
			$hasError = true;
		} else {
			$second_name = trim($_POST['contact_second_name']);
		}

		//Check to make sure that the first name field is not empty
		if(trim($_POST['contact_first_name']) == '') {
			$hasError = true;
		} else {
			$first_name = trim($_POST['contact_first_name']);
		}

		//Check to make sure comments were entered
		if(trim($_POST['message']) == '') {
			$hasError = true;
		} else {
			if(function_exists('stripslashes')) {
				$message = htmlentities(trim($_POST['message']));
			} else {
				$message = trim($_POST['message']);
			}
		}

	//If there is no error, send the email
	if(!isset($hasError)){
		$mail = '[email protected]'; // Déclaration de l'adresse de destination.
		if (!preg_match("#^[a-z0-9._-]+@(hotmail|live|msn).[a-z]{2,4}$#", $mail)) // On filtre les serveurs qui présentent des bogues.
		{
			$passage_ligne = "\r\n";
		}
		else
		{
			$passage_ligne = "\n";
		}

		//Déclaration des messages au format texte et au format HTML.
		$message_html = 
		"<html>
			<head>
			</head>

			<body><h1><center>Formulaire de contact</center></h1>"
			.
			"<br /><strong>" . htmlentities($_POST['contact_first_name']) . " " . htmlentities($_POST['contact_second_name']) . "</strong>"
			. " " . "vous a contacté, en raison de : " . htmlentities($_POST['subject']) . "<br /> <br />" . htmlentities($_POST['message']) .
			"<br /></body>
		</html>";
		 
		//Création de la boundary
		$boundary = "-----=".md5(rand());
		 
		//Définition du sujet.
		$sujet = htmlentities($_POST['subject']);
		//
		 
		//Création du header de l'e-mail.
        $header = "From: \"".htmlentities($_POST['contact_first_name']) .htmlentities($_POST['contact_second_name'])."\"<".$email.">".$passage_ligne;
        $header.= "Reply-to: \"".htmlentities($_POST['contact_first_name']) . htmlentities($_POST['contact_second_name'])."\"<".$email.">".$passage_ligne;
        $header.= "MIME-Version: 1.0".$passage_ligne;
        $header.= "X-Priority: 3".$passage_ligne;
        $header.= "X-Confirm-Reading-To: ".$email.$passage_ligne;
        $header.= "Content-Type: text/html; charset=\"utf8\"".$passage_ligne."$boundary".$passage_ligne;
        //
  
		//Ajout du message au format HTML
		$message= $passage_ligne.$message_html.$passage_ligne;
		$message.= $passage_ligne."--".$boundary."--".$passage_ligne;
		//
		
		/* Expression régulière permettant de vérifier qu'aucun en-tête n'est inséré dans nos champs */
		$regex_head = '/[\n\r]/';  
		 
		/* On vérifie qu'il n'y a aucun header dans les champs */ 
		if (preg_match($regex_head, $email) 
		    || preg_match($regex_head, $_POST['contact_first_name']) 
		    || preg_match($regex_head, $_POST['contact_second_name'])
		    || preg_match($regex_head, $_POST['subject'])
			|| preg_match($regex_head, $_POST['message']))
		{  
		    $alert = setAlert('Entêtes interdites dans les champs du formulaire', 'danger');
		}
		else
		{
			//Envoi de l'e-mail.
			if (mail($mail,$sujet,$message,$header)){
				setAlert('Le mail a bien été envoyé', 'success');
		} 
	   		else
	   			setAlert('Echec de l\' envoi du mail', 'danger');
	   		}
		}   
		 
		/* On affiche l'erreur s'il y en a une */ 
		if (!empty($alert))
		{
		    echo $alert;
		} 
	}
?>


Re: Formulaire de contact sécurisé

Posté : 11 juil. 2014, 09:02
par ynx
Effectivement l'entête Charset défini l'encodage du contenu du mail mais pas du sujet.

Au lieu d'effectuer un htmlentities sur le sujet (puisque de toute façon celui-ci n'est pas interprété en html), tu peux essayer de le passer en base64 avec cette syntaxe :
$newsubject = '=?UTF-8?B?'.base64_encode($subject).'?=';
Plus d'info : http://stackoverflow.com/questions/4389 ... ng-problem

Bonne journée