🍏
SAE203
  • 📖CM1 : Présentation de la SAE
  • 💾CM2 : Introduction à GitHub
  • 🎆TD01 : intégration 1/2
  • 🎆TD02 : intégration 2/2
  • 🎆CM3 : Template et responsive
  • 📔TD03 : Formulaire et traitement
  • 🗓️TD04 : filter_var et filtrage des données des formulaires en PHP
  • 🤝CM4 : Eco-conception & accessibilité
  • 💾TD05 : github
  • 🌳TD06 : Eco-conception & accessibilité
  • 🐛TP01 : réalisation de la page listing.php
  • 🌐TD07 : HEBERGEMENT SITE SAE203
  • 🌐TD08 : Les Clés du DevOps
  • 🏆BILAN des rendus
  • 😇Guide de Dépannage Git
  • **anciennes pages ci-dessous**
  • 🐛ancien TP01 : réalisation de la page listing.php
  • 🗓️ancien TD04 : vérification front
  • 📚ancien TD05 : MYSQL en ligne de commandes
  • *************************
  • 📖CM5 : Présentation de la semaine 2
  • 🤩TD 09 et 10 : librairie CRUD en PHP (1/2)
  • 😎TD 11 et 12 : librairie CRUD en PHP (2/2)
  • 🏍️TP 02 : Recherche : autocomplétion du formulaire + résultats
  • 🔐TD 13: Les secrets du htaccess
  • 🐛TP 03: débugage
  • ✅Bilan des rendus de la 2ieme semaine
Propulsé par GitBook
Sur cette page
  • 1) Sécurité des champs d'un formulaire de connexion :
  • 2) Sécurité des champs d'un formulaire de renseignement :
  • 3) Sécurité de votre formulaire de recherche SAE203 :
  • 4) Pour aller plus loin :
Exporter en PDF

TD04 : filter_var et filtrage des données des formulaires en PHP

Lorsque nous utilisons des formulaires sur une page web, leur traitement en PHP doit assurer la sécurité de leur contenu. Dans cette séance, on va essayer de comprendre ce qui peut mal se passer lors du traitement des informations par le code PHP.

1) Sécurité des champs d'un formulaire de connexion :

On donne le formulaire de connexion "form1.php" suivant :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
    </head>
    <body>
        <h1>Connexion</h1>
        <form method="post" action="t1.php">
            <label for="email">e-mail : </label>
            <input type="text" name="email" id="email"><br />
            <label for="mdp">mot de passe : </label>
            <input type="password" name="mdp" id="mdp"><br />
            <input type="submit" value="Vérifier">
        </form>
    </body>
</html>

Dans ce formulaire, on demande à l'utilisateur de définir une adresse e-mail et un mot de passe pour sa connexion. Le champ "e-mail" est de type "text", le champ "mdp" est de type "password".

On donne le fichier de traitement "t1.php" :

<?php
    if ( (empty($_POST['email'])) || (empty($_POST['mdp'])) ){
        header('Location: form1.php');
    }

    echo '<p>'.$_POST['email'].'</p>'."\n";
    echo '<p>'.$_POST['mdp'].'</p>'."\n";

Dans ce fichier de traitement, on regarde si les deux champs ont bien été remplis correctement. S'il en manque un des deux, on retourne à la page du formulaire. Si les deux champs sont remplis, on affiche leur contenu (d'ailleurs en passant, ce n'est pas bien d'afficher le contenu d'un mot de passe...).

  • Envoyez ces deux fichiers sur votre VPS dans le dossier "public_html/travaux/sae203/td06/". Testez le code en entrant un e-mail "normal" et un mot de passe "bidon" : "toto1234" par exemple. Que se passe-t-il au niveau de l'affichage par la page de traitement (y a-t-il un problème) ?

  • Maintenant sur votre navigateur, retournez sur la page du formulaire et entrez : toto@toto.to<script>alert('script 1');</script> dans le champ "e-mail" et toto1234<script>alert('script 2');</script> dans le champ "mdp". Validez votre formulaire, que se passe-t-il sur la page de traitement ?

Il y a donc possibilité d'injecter du code Javascript dans un champ de type "text" dans un formulaire (c'est de l'injection de code XSS). Cela donne un problème de sécurité, n'importe qui peut envoyer des scripts dans vos champs de formulaire. Ici, c'est juste un affichage mais on pourrait injecter un script qui redirige vers une autre page...

Il faut donc, pour n'importe quelle donnée, respecter les trois étapes suivantes :

  1. Sanitize input (assainir les entrées)

  2. Validate data (valider les données)

  3. Escape output (échapper les sorties)

Dans notre cas, le champ qui pose problème est le champ "email" car le champ "mdp" n'a pas besoin d'être affiché (et ne doit jamais l'être sur un site), même sa version cryptée ! Mettez en commentaire la ligne //echo '<p>'.$_POST['mdp'].'</p>'."\n"; dans votre page de traitement "t1.php".

  • Modifiez votre code pour "assainir", "valider" et "échapper" le champ email. Envoyez votre nouveau code sur votre VPS, testez ce qui se passe avec "toto@toto.to<script>alert('script 1');</script>" dans le champ "e-mail" et "toto1234<script>alert('script 2');</script>" dans le champ mot de passe. Normalement, votre code n'affichera plus les fenêtres pop-up "alert()".

Pour éviter ce genre de problème, vous pouvez passer le champ "email" du type "text" au type "email" qui existe en HTML.

2) Sécurité des champs d'un formulaire de renseignement :

On donne le code du formulaire "form2.php" ici :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
    </head>
    <body>
        <h1>Connexion</h1>
        <form method="post" action="t2.php">
            <label for="prenom">Votre prénom : </label>
            <input type="text" name="prenom" id="prenom"><br />
            <label for="age">Votre âge : </label>
            <input type="text" name="age" id="age"> ans.<br />
            <input type="submit" value="Envoyer">
        </form>
    </body>
</html>
  • On donne le fichier de traitement "t2.php" :

<?php
    if ( (empty($_POST['prenom'])) || (empty($_POST['age'])) ) {
        header('Location: form2.php');
    }

    echo '<p>Votre prénom : '.$_POST['prenom'].'</p>'."\n";
    echo '<p>Votre âge : '.$_POST['age'].'</p>'."\n";
  • Envoyez ces deux fichiers sur votre VPS dans le dossier "public_html/travaux/sae203/td06/". Testez le code en entrant Robert<script>alert('Prénom pas sûr !')</script> et 20<script>alert('Âge pas sûr non plus !')</script>. Que se passe-t-il au niveau de l'affichage par la page de traitement (y a-t-il un problème) ?

  • Appliquez l'assainissement, la validation et l'échappement dans le fichier de traitement "t2.php". Testez votre code avec Robert<script>alert('Prénom pas sûr !')</script> et 20<script>alert('Âge pas sûr non plus !')</script> jusqu'à ce qu'il n'y ait plus de problème d'injection de code Javascript dans vos champs de formulaire.

  • En résumé, pour garantir un premier niveau de sécurité, il faut mettre les types qui correspondent aux champs dans les champs de formulaire : <input type= "email"> pour un e-mail, "number" pour un nombre, "date" pour une date... Tout mettre en <input type="text" ...> n'est pas une bonne idée !

On aurait pu aussi démarrer les sessions sur les pages de notre site et choisir, au lieu d'afficher des erreurs au niveau de la page de traitement, de les passer en session à la page du formulaire pour prévenir l'utilisateur qu'un champ n'est pas correctement rempli dans le formulaire (on l'a déjà fait en S1 en SAE105...).

3) Sécurité de votre formulaire de recherche SAE203 :

Afin de vérifier si vous avez bien compris la sécurisation de vos données de champs de formulaire, modifiez le code de votre formulaire de recherche et de votre page de traitement "reponse_recherche.php".

Testez votre code en mettant un script dans le champ de recherche par nom/prénom d'un auteur, par exemple Albert Uderzo<script>alert('Danger !!!')</script>. Si votre protection fonctionne bien, vous ne devez pas voir la fenêtre pop-up qui affiche "Danger !!!" apparaître lors du traitement de votre formulaire.

4) Pour aller plus loin :

Quelques liens à lire pour comprendre un peu mieux les enjeux de la sécurité de vos pages web de traitement de formulaires avec PHP :

PrécédentTD03 : Formulaire et traitementSuivantCM4 : Eco-conception & accessibilité

Dernière mise à jour il y a 2 ans

En PHP, la fonction d'assainissement et de validation des données est et la fonction d'échappement des caractères spéciaux dans les chaînes est .

🗓️
filter_var()
htmlentities()
PHP good security practices
Sécurité PHP
Filtres de nettoyage PHP
Filtres de validation PHP
Fonction de nettoyage avant affichage