[RESOLU] Sécurisation formulaire php via in controle de la page d'envoi des données.

Eléphant du PHP | 89 Messages

06 avr. 2022, 22:33

Bonsoir,

je souhaite sécuriser mon formulaire de contact en vérifiant l'URL d'envoi du formulaire.

Le code ci-dessous donne une page blanche:
if(isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] == "url d'envoi du formulaire"){
    if($_SERVER['REQUEST_METHOD'] == 'POST'){
        // On vérifie que le champ "Pot de miel" est vide
        if(isset($_POST['raison']) && empty($_POST['raison'])){
            // On vérifie que tous les champs sont remplis
            if(
                isset($_POST['nom']) && !empty($_POST['nom']) &&
                isset($_POST['sujet']) && !empty($_POST['sujet']) &&
                isset($_POST['email']) && !empty($_POST['email']) &&
                isset($_POST['message']) && !empty($_POST['message'])
            ){
                // On "nettoie" le contenu
                $nom = strip_tags($_POST['nom']);
                $sujet = strip_tags($_POST['sujet']);
                $email = strip_tags($_POST['email']);
                $message = htmlspecialchars($_POST['message']);

                // Ici on traite les données

                echo " Message de {$nom} envoyé";

            }
        }

    }else{
        http_response_code(405);
        echo "Méthode non autorisée";
    }    
}
Merci pour votre aide.

PS: Je suis hébergé chez OVH: possible que la fonction $_SERVER['HTTP_REFERER'] ne soit pas supportée chez eux?

Mammouth du PHP | 2703 Messages

06 avr. 2022, 22:50

Le code ci-dessous donne une page blanche:
tutoriels/page-blanche-script-php-comme ... 73178.html

perso, je bloque le referer donc je ne pourrais pas utiliser ce formulaire si une telle exigence est mise en place.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

07 avr. 2022, 00:27

+1, ce n'est pas une méthode de sécurisation fiable et il risque d'y avoir des effets de bord.
Si tu veux sécuriser correctement ton formulaire, il faut filtrer les variables reçues en n'autorisant que ce que tu attends.
Ça tombe bien PHP a des fonctions pour celà avec des filtres tout fait :
https://php.net/filter_var ou https://php.net/filter_input
Et ensuite :
- Filtres de validation : https://www.php.net/manual/fr/filter.fi ... lidate.php
- Filtres de nettoyage : https://www.php.net/manual/fr/filter.fi ... nitize.php
Quand tout le reste a échoué, lisez le mode d'emploi...

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

07 avr. 2022, 08:47

A noter aussi que pour éviter le fait que ton formulaire ne soit pas envoyé depuis ailleurs que ta page, la meilleure solution c'est de mettre en place ce qu'on appelle un token anti-CSRF, en gros un token valable quelques minutes que tu génères à la volée lors de l'affichage de ton formulaire et que tu mets dans un champ input caché du formulaire.
Et à la réception d'un POST tu vérifies si le token est bien là et si il est encore valide.
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 89 Messages

09 avr. 2022, 15:40

+1, ce n'est pas une méthode de sécurisation fiable et il risque d'y avoir des effets de bord.
Si tu veux sécuriser correctement ton formulaire, il faut filtrer les variables reçues en n'autorisant que ce que tu attends.
Ça tombe bien PHP a des fonctions pour celà avec des filtres tout fait :
https://php.net/filter_var ou https://php.net/filter_input
Et ensuite :
- Filtres de validation : https://www.php.net/manual/fr/filter.fi ... lidate.php
- Filtres de nettoyage : https://www.php.net/manual/fr/filter.fi ... nitize.php
Merci pour votre réponse.
Je contrôle que les champs doivent être remplis et je reçois quand même des spams, exemple ci-dessous:
Nom: Annotationsdpc
E-Mail de contact: [email protected]
N° de téléphone: 81669141867
Commentaires: Libraries of the Carolingian era). IN
<?php

if($_SERVER['REQUEST_METHOD'] == 'POST'){
    // On vérifie que le champ "Pot de miel" est vide
    if(isset($_POST['raison']) && empty($_POST['raison'])){
        // On vérifie que tous les champs sont remplis
        if(
            isset($_POST['nom']) && !empty($_POST['nom']) &&
            isset($_POST['sujet']) && !empty($_POST['sujet']) &&
            isset($_POST['email']) && !empty($_POST['email']) &&
            isset($_POST['message']) && !empty($_POST['message'])
        ){
            // On "nettoie" le contenu
            $nom = strip_tags($_POST['nom']);
            $sujet = strip_tags($_POST['sujet']);
            $email = strip_tags($_POST['email']);
            $message = htmlspecialchars($_POST['message']);

            // Ici vous devrez traiter les données

            $msg = "Nom:\t$_POST[nom]\n";
		$msg .= "E-Mail de contact:\t$_POST[email]\n";
		$msg .= "N° de téléphone:\t$_POST[phone]\n";
		$msg .= "Commentaires:\t$_POST[message]\n";
		$msg .= "Champ pot de miel:\t$_POST[raison]\n";

	$recipient = "[email protected]";
	$subject = "Formulaire de reservation site";

	$mailheaders = "From: $_POST[email]\n";
	$mailheaders .= "Reply-To: $_POST[email]\n\n";

	mail($recipient, $subject, $msg, $mailheaders);
	header('Location:http://monnomdedomaine.be/merci.html');

        }
    }

}else{
    http_response_code(405);
    echo "Méthode non autorisée";
}
J'ai ajouté un champ "pot de miel" en caché. Le spammer ne le remplit pas, mais je me fais néanmoins spammer (le champ "pot de miel" n'est pas rempli, mais le formulaire est quand même envoyé):
Nom: Annotationsdpc
E-Mail de contact: [email protected]
N° de téléphone: 81669141867
Commentaires: Libraries of the Carolingian era). IN
Champ pot de miel:

Je me dis donc que le robot ne passe pas via mon formulaire, mais via le fichier de traitement.php directement ...
J'essaye donc de supprimer les accès en direct au fichier traitement.php.
Si je saisis ceci (http://www.paysdessaveurs.be/traitement0604.php) dans l'url, j'ai bien le message ci-dessous:
Méthode non autorisée.

Merci pour vos "lumières".

Mammouth du PHP | 2703 Messages

09 avr. 2022, 15:45

c'est que le robot accède au fichier en méthode post, pas en get.

Eléphant du PHP | 89 Messages

09 avr. 2022, 15:52

c'est que le robot accède au fichier en méthode post, pas en get.
ok mais le champ "pot de miel" devrait être rempli par le robot, non?
Or ce n'est pas le cas.

Mammouth du PHP | 2703 Messages

09 avr. 2022, 15:58

if(isset($_POST['raison']) && empty($_POST['raison'])){

avec une telle condition, il faut que le champ soit vide.

Eléphant du PHP | 89 Messages

09 avr. 2022, 16:13

if(isset($_POST['raison']) && empty($_POST['raison'])){

avec une telle condition, il faut que le champ soit vide.
Oui en effet, si le champ est vide, cela veut dire qu'un robot ne l'a pas rempli, alors il traite les infos du formulaires.
S'il est rempli, méthode non valable.
Mon code n'est pas bon?

Mammouth du PHP | 2703 Messages

09 avr. 2022, 16:19

si le code veut empêcher les robots de poster et que les robots peuvent quand même poster, oui, le code n'est pas bon.

Eléphant du PHP | 89 Messages

09 avr. 2022, 16:21

si le code veut empêcher les robots de poster et que les robots peuvent quand même poster, oui, le code n'est pas bon.
et vous pouvez me mettre sur la piste de ce qui n'est pas bon?

Merci pour votre temps.

Mammouth du PHP | 2703 Messages

09 avr. 2022, 16:31

comme le robot peut tester de poster en remplissant tous les champs ou pas tous, il faut ruser, en masquant un champ name="email" en css, et en vérifiant si ce champ est rempli. le vrai champ email pour les humains a un autre nom.

Eléphant du PHP | 89 Messages

09 avr. 2022, 16:38

comme le robot peut tester de poster en remplissant tous les champs ou pas tous, il faut ruser, en masquant un champ name="email" en css, et en vérifiant si ce champ est rempli. le vrai champ email pour les humains a un autre nom.
Ok clair.
J'ai déjà un champ caché: <input type="hidden" name="raison">
J'en ajoute un 2ème? <input type="hidden" name="mail"> ?

Merci.

Mammouth du PHP | 2703 Messages

09 avr. 2022, 16:40

non, vous mettez un champ input type="text", c'est en css que vous le masquez aux humains qui donc ne le remplissent pas. le robot, lui, va vouloir remplir ce champ name="email", qui, si il est rempli, fait que l'email ne vous ai pas envoyé.

Eléphant du PHP | 89 Messages

10 avr. 2022, 08:57

non, vous mettez un champ input type="text", c'est en css que vous le masquez aux humains qui donc ne le remplissent pas. le robot, lui, va vouloir remplir ce champ name="email", qui, si il est rempli, fait que l'email ne vous ai pas envoyé.
Merci.

Comme ceci?

La zone courriel est le "vrai" mail à remplir par le visiteur.
La zone "email" est la fake zone de mail:

Code : Tout sélectionner

<p> <label for="email">E-mail :</label> <input type="courriel" name="courriel" id="courriel"> </p> <p> <input type="email" style="visibility:hidden" name="email" id="email"> </p>