Tutoriel Sécurisez vos formulaires - PHP

Walky 🇫🇷

Développeur
Développeur
Inscription
18 Octobre 2012
Messages
1 254
Réactions
1 149
Points
10 840
    Réponse de Walky 🇫🇷 Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #1
header1.png
Bonjour à tous , aujourd'hui nous allons, ensemble, apprendre à sécuriser nos formulaires HTML.

header2.png
Bien évidemment, nous n'utiliserons pas de vérification Captcha ou ReCaptcha pour ne pas embêter le visiteur.

Le principe va consister à générer une clé secrète pour l'insérer dans un champ invisible dans notre formulaire.
Et lors de l'envoi du formulaire, nous allons vérifier la validité de la clé.

Pour générer notre clé secrètre, nous utiliserons deux paramètres:

  • Un salt (de préférence tapé à la main)
  • Le timestamp actuel
Veillez à ne pas utiliser de variables statiques, voilà pourquoi j'utilise le timestamp .

header3.png
Comme vu dans la partie précédente, nous utiliserons deux paramètres, mais vous vous doutez bien qu'on ne les affichera pas directement dans le formulaire (même en champ masqué), on va donc utiliser une fonction PHP permettant de crypter les données , dans ce tutoriel je vais utiliser SHA1.

Commençons donc par créer notre seul et unique fichier, qui contiendra le formulaire HTML ainsi que le code PHP .


Je tiens à vous informer que j'utiliserai la POO tout au long du tutoriel.
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9'; // tapé à la main
    public $erreur = null; // ici, sera stocké l'erreur

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }
}
On constate donc qu'il y a une variable de class: $salt, contenant notre salt, ainsi que 2 fonctions. L'une, exécutée directement lors du chargement de la page, et une autre permettant de générer la clé secrète .

À cela on va ajouter le formulaire HTML , de base un formulaire non sécurisé ressemble à ceci:
HTML:
<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
On va donc stocker notre clé secrète dans une variable, générée par notre fonction créée précédemment.

PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();
Et l'insérer dans un champ invisible dans le formulaire HTML
PHP:
<input type="hidden" name="key" value="<?= $secretKey ?>" />
Il ne nous reste donc, seulement la vérification de la clé ! Et afficher l'erreur dans le formulaire HTML
PHP:
public function verifyKey()
{
    if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
    {
        $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    $secretKey = sha1($_SESSION['key'] . $this->salt);
    if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    return true;
}
En dehors de la class, nous avons donc quelque chose du genre
PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
header4.png
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9';
    public $erreur = null;

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key']))
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }

    public function verifyKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        return true;
    }
}

$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
?>

<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <?php
            if ($class->erreur)
            {
                echo $class->erreur;
            }
        ?>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="hidden" name="key" value="<?= $secretKey ?>" />
            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
header5.png
Je vous remercie d'avoir lu ce tutoriel, et n'hésitez pas à me faire part de vos erreurs / bugs rencontrés si vous utilisez le système que je viens de vous présenter ::cool::

Merci @Lawid SEC pour les headers :love:

Walky
 

Fichiers joints

Louki

Ancien staff
Ancien staff
Inscription
8 Juin 2013
Messages
5 296
Réactions
5 155
Points
11 657
    Réponse de Louki Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #2
Voir la pièce jointe 101360
Bonjour à tous , aujourd'hui nous allons, ensemble, apprendre à sécuriser nos formulaires HTML.

Voir la pièce jointe 101356
Bien évidemment, nous n'utiliserons pas de vérification Captcha ou ReCaptcha pour ne pas embêter le visiteur.

Le principe va consister à générer une clé secrète pour l'insérer dans un champ invisible dans notre formulaire.
Et lors de l'envoi du formulaire, nous allons vérifier la validité de la clé.

Pour générer notre clé secrètre, nous utiliserons deux paramètres:

  • Un salt (de préférence tapé à la main)
  • Le timestamp actuel
Veillez à ne pas utiliser de variables statiques, voilà pourquoi j'utilise le timestamp .

Comme vu dans la partie précédente, nous utiliserons deux paramètres, mais vous vous doutez bien qu'on ne les affichera pas directement dans le formulaire (même en champ masqué), on va donc utiliser une fonction PHP permettant de crypter les données , dans ce tutoriel je vais utiliser SHA1.

Commençons donc par créer notre seul et unique fichier, qui contiendra le formulaire HTML ainsi que le code PHP .


Je tiens à vous informer que j'utiliserai la POO tout au long du tutoriel.
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9'; // tapé à la main
    public $erreur = null; // ici, sera stocké l'erreur

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }
}
On constate donc qu'il y a une variable de class: $salt, contenant notre salt, ainsi que 2 fonctions. L'une, exécutée directement lors du chargement de la page, et une autre permettant de générer la clé secrète .

À cela on va ajouter le formulaire HTML , de base un formulaire non sécurisé ressemble à ceci:
HTML:
<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
On va donc stocker notre clé secrète dans une variable, générée par notre fonction créée précédemment.

PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();
Et l'insérer dans un champ invisible dans le formulaire HTML
PHP:
<input type="hidden" name="key" value="<?= $secretKey ?>" />
Il ne nous reste donc, seulement la vérification de la clé ! Et afficher l'erreur dans le formulaire HTML
PHP:
public function verifyKey()
{
    if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
    {
        $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    $secretKey = sha1($_SESSION['key'] . $this->salt);
    if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    return true;
}
En dehors de la class, nous avons donc quelque chose du genre
PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9';
    public $erreur = null;

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key']))
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }

    public function verifyKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        return true;
    }
}

$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
?>

<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <?php
            if ($class->erreur)
            {
                echo $class->erreur;
            }
        ?>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="hidden" name="key" value="<?= $secretKey ?>" />
            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
Je vous remercie d'avoir lu ce tutoriel, et n'hésitez pas à me faire part de vos erreurs / bugs rencontrés si vous utilisez le système que je viens de vous présenter ::cool::

Merci @Lawid SEC pour les headers :love:

Walky
Yeah, beau topic Walky ! ::):
 

Djamel SEC

Ancien staff
Ancien staff
Inscription
24 Août 2012
Messages
19 497
Réactions
9 739
Points
19 900
    Réponse de Djamel SEC Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #3
Énorme Walky !
 

Ichigo' SEC

Super-modérateur
Super-modérateur
Inscription
24 Septembre 2011
Messages
6 661
Réactions
3 931
Points
12 060
    Réponse de Ichigo' SEC Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #4
Voir la pièce jointe 101360
Bonjour à tous , aujourd'hui nous allons, ensemble, apprendre à sécuriser nos formulaires HTML.

Voir la pièce jointe 101356
Bien évidemment, nous n'utiliserons pas de vérification Captcha ou ReCaptcha pour ne pas embêter le visiteur.

Le principe va consister à générer une clé secrète pour l'insérer dans un champ invisible dans notre formulaire.
Et lors de l'envoi du formulaire, nous allons vérifier la validité de la clé.

Pour générer notre clé secrètre, nous utiliserons deux paramètres:

  • Un salt (de préférence tapé à la main)
  • Le timestamp actuel
Veillez à ne pas utiliser de variables statiques, voilà pourquoi j'utilise le timestamp .

Comme vu dans la partie précédente, nous utiliserons deux paramètres, mais vous vous doutez bien qu'on ne les affichera pas directement dans le formulaire (même en champ masqué), on va donc utiliser une fonction PHP permettant de crypter les données , dans ce tutoriel je vais utiliser SHA1.

Commençons donc par créer notre seul et unique fichier, qui contiendra le formulaire HTML ainsi que le code PHP .


Je tiens à vous informer que j'utiliserai la POO tout au long du tutoriel.
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9'; // tapé à la main
    public $erreur = null; // ici, sera stocké l'erreur

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }
}
On constate donc qu'il y a une variable de class: $salt, contenant notre salt, ainsi que 2 fonctions. L'une, exécutée directement lors du chargement de la page, et une autre permettant de générer la clé secrète .

À cela on va ajouter le formulaire HTML , de base un formulaire non sécurisé ressemble à ceci:
HTML:
<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
On va donc stocker notre clé secrète dans une variable, générée par notre fonction créée précédemment.

PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();
Et l'insérer dans un champ invisible dans le formulaire HTML
PHP:
<input type="hidden" name="key" value="<?= $secretKey ?>" />
Il ne nous reste donc, seulement la vérification de la clé ! Et afficher l'erreur dans le formulaire HTML
PHP:
public function verifyKey()
{
    if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
    {
        $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    $secretKey = sha1($_SESSION['key'] . $this->salt);
    if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    return true;
}
En dehors de la class, nous avons donc quelque chose du genre
PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9';
    public $erreur = null;

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key']))
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }

    public function verifyKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        return true;
    }
}

$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
?>

<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <?php
            if ($class->erreur)
            {
                echo $class->erreur;
            }
        ?>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="hidden" name="key" value="<?= $secretKey ?>" />
            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
Je vous remercie d'avoir lu ce tutoriel, et n'hésitez pas à me faire part de vos erreurs / bugs rencontrés si vous utilisez le système que je viens de vous présenter ::cool::

Merci @Lawid SEC pour les headers :love:

Walky
Lourd ! :panic:
 

Espi0n

Membre Premium Retraité
Premium
Inscription
27 Août 2015
Messages
2 339
Réactions
1 077
Points
5 471
    Réponse de Espi0n Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #5
Pas Lourd :trollface:
 

xRwizz

Ancien staff
Ancien staff
Inscription
12 Juin 2013
Messages
18 240
Réactions
5 531
Points
16 058
    Réponse de xRwizz Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #7
Voir la pièce jointe 101360
Bonjour à tous , aujourd'hui nous allons, ensemble, apprendre à sécuriser nos formulaires HTML.

Voir la pièce jointe 101356
Bien évidemment, nous n'utiliserons pas de vérification Captcha ou ReCaptcha pour ne pas embêter le visiteur.

Le principe va consister à générer une clé secrète pour l'insérer dans un champ invisible dans notre formulaire.
Et lors de l'envoi du formulaire, nous allons vérifier la validité de la clé.

Pour générer notre clé secrètre, nous utiliserons deux paramètres:

  • Un salt (de préférence tapé à la main)
  • Le timestamp actuel
Veillez à ne pas utiliser de variables statiques, voilà pourquoi j'utilise le timestamp .

Comme vu dans la partie précédente, nous utiliserons deux paramètres, mais vous vous doutez bien qu'on ne les affichera pas directement dans le formulaire (même en champ masqué), on va donc utiliser une fonction PHP permettant de crypter les données , dans ce tutoriel je vais utiliser SHA1.

Commençons donc par créer notre seul et unique fichier, qui contiendra le formulaire HTML ainsi que le code PHP .


Je tiens à vous informer que j'utiliserai la POO tout au long du tutoriel.
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9'; // tapé à la main
    public $erreur = null; // ici, sera stocké l'erreur

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }
}
On constate donc qu'il y a une variable de class: $salt, contenant notre salt, ainsi que 2 fonctions. L'une, exécutée directement lors du chargement de la page, et une autre permettant de générer la clé secrète .

À cela on va ajouter le formulaire HTML , de base un formulaire non sécurisé ressemble à ceci:
HTML:
<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
On va donc stocker notre clé secrète dans une variable, générée par notre fonction créée précédemment.

PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();
Et l'insérer dans un champ invisible dans le formulaire HTML
PHP:
<input type="hidden" name="key" value="<?= $secretKey ?>" />
Il ne nous reste donc, seulement la vérification de la clé ! Et afficher l'erreur dans le formulaire HTML
PHP:
public function verifyKey()
{
    if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
    {
        $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    $secretKey = sha1($_SESSION['key'] . $this->salt);
    if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    return true;
}
En dehors de la class, nous avons donc quelque chose du genre
PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9';
    public $erreur = null;

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key']))
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }

    public function verifyKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        return true;
    }
}

$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
?>

<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <?php
            if ($class->erreur)
            {
                echo $class->erreur;
            }
        ?>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="hidden" name="key" value="<?= $secretKey ?>" />
            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
Je vous remercie d'avoir lu ce tutoriel, et n'hésitez pas à me faire part de vos erreurs / bugs rencontrés si vous utilisez le système que je viens de vous présenter ::cool::

Merci @Lawid SEC pour les headers :love:

Walky
Du lourd, beau topic Walky ::cool::
 

ॐ Devkush ॐ

Banni
Premium
Inscription
30 Octobre 2015
Messages
582
Réactions
206
Points
2 176
    Réponse de ॐ Devkush ॐ Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #8
100% Fonctionelle merci pour ce tuto ;)
 

❤cœur

Le plus beau
Inscription
21 Juin 2014
Messages
1 158
Réactions
378
Points
4 788
    Réponse de ❤cœur Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #9
Voir la pièce jointe 101360
Bonjour à tous , aujourd'hui nous allons, ensemble, apprendre à sécuriser nos formulaires HTML.

Voir la pièce jointe 101356
Bien évidemment, nous n'utiliserons pas de vérification Captcha ou ReCaptcha pour ne pas embêter le visiteur.

Le principe va consister à générer une clé secrète pour l'insérer dans un champ invisible dans notre formulaire.
Et lors de l'envoi du formulaire, nous allons vérifier la validité de la clé.

Pour générer notre clé secrètre, nous utiliserons deux paramètres:

  • Un salt (de préférence tapé à la main)
  • Le timestamp actuel
Veillez à ne pas utiliser de variables statiques, voilà pourquoi j'utilise le timestamp .

Comme vu dans la partie précédente, nous utiliserons deux paramètres, mais vous vous doutez bien qu'on ne les affichera pas directement dans le formulaire (même en champ masqué), on va donc utiliser une fonction PHP permettant de crypter les données , dans ce tutoriel je vais utiliser SHA1.

Commençons donc par créer notre seul et unique fichier, qui contiendra le formulaire HTML ainsi que le code PHP .


Je tiens à vous informer que j'utiliserai la POO tout au long du tutoriel.
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9'; // tapé à la main
    public $erreur = null; // ici, sera stocké l'erreur

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }
}
On constate donc qu'il y a une variable de class: $salt, contenant notre salt, ainsi que 2 fonctions. L'une, exécutée directement lors du chargement de la page, et une autre permettant de générer la clé secrète .

À cela on va ajouter le formulaire HTML , de base un formulaire non sécurisé ressemble à ceci:
HTML:
<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
On va donc stocker notre clé secrète dans une variable, générée par notre fonction créée précédemment.

PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();
Et l'insérer dans un champ invisible dans le formulaire HTML
PHP:
<input type="hidden" name="key" value="<?= $secretKey ?>" />
Il ne nous reste donc, seulement la vérification de la clé ! Et afficher l'erreur dans le formulaire HTML
PHP:
public function verifyKey()
{
    if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
    {
        $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    $secretKey = sha1($_SESSION['key'] . $this->salt);
    if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
    {
        $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
        return false;
    }

    return true;
}
En dehors de la class, nous avons donc quelque chose du genre
PHP:
$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
PHP:
<?php

class SubmitForm
{
    public $salt   = '782hdbbab001mbdjbxaoi9';
    public $erreur = null;

    public function __construct()
    {
        session_start(); // on démarre la session
        $_SESSION['key'] = uniqid(microtime(true)); // on stocke notre clé relative au timestamp dans une variable de session
    }

    public function buildKey()
    {
        if (!isset($_SESSION['key']))
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        return $secretKey;
    }

    public function verifyKey()
    {
        if (!isset($_SESSION['key'])) // la variable de session "key" doit obligatoirement exister
        {
            $this->erreur = 'Une erreur s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        if (!isset($_POST['key'])) // le formulaire doit contenir le champ "key"
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        $secretKey = sha1($_SESSION['key'] . $this->salt);
        if ($_POST['key'] != $secretKey) // la clé secrète envoyée doit correspondre exactement à celle créée par la fonction
        {
            $this->erreur = 'Une erreur de sécurité s\'est produite, veuillez rafraîchir la page.';
            return false;
        }

        return true;
    }
}

$class     = new SubmitForm();
$secretKey = $class->buildKey();

if ($_SERVER['REQUEST_METHOD'] == 'post') // on vérifie la clé seulement si la requête envoyée est au format POST
{
    $class->verifyKey();
}
?>

<!DOCTYPE html>
<html>
    <head>
        <!-- Vos données -->
    </head>
    <body>
        <?php
            if ($class->erreur)
            {
                echo $class->erreur;
            }
        ?>
        <form method="post" action="/">
            <input type="text" name="prenom" placeholder="Prénom..." />
            <input type="text" name="age" placeholder="Age..." />

            <input type="hidden" name="key" value="<?= $secretKey ?>" />
            <input type="submit" value="Soumettre" />
        </form>
    </body>
</html>
Je vous remercie d'avoir lu ce tutoriel, et n'hésitez pas à me faire part de vos erreurs / bugs rencontrés si vous utilisez le système que je viens de vous présenter ::cool::

Merci @Lawid SEC pour les headers :love:

Walky
Premier Developpédacteur ?
 

WhiiTe'

Ancien staff
Ancien staff
Inscription
22 Octobre 2011
Messages
14 090
Réactions
7 706
Points
16 005
    Réponse de WhiiTe' Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #11
BG Walky ! :cool:
 
M

membre150711

Invité
    Réponse de membre150711 Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #12
Ça me fait penser au trophée Mario :pensif:
 

Insomniaque97

Donateur
Premium
Inscription
21 Juillet 2015
Messages
1 090
Réactions
503
Points
3 775
    Réponse de Insomniaque97 Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #13
Merci beaucoup, très intéressant !
 

Rivals

Ancien staff
Premium
Inscription
27 Août 2016
Messages
600
Réactions
498
Points
2 446
    Réponse de Rivals Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #14
Bonjour Walky SEC ,

Je ne veux pas être méchant mais ça ne sécurise en rien ton formulaire à l'heure d'aujourd'hui, avec
Vous devez vous inscrire ou vous connecter pour voir les liens ! (c'est gratuit et rapide 🚀)
par exemple on peut très facilement spammer ton formulaire et rendre ton token inutile :p

PHP:
public $erreur = null;
Equivaut à :
PHP:
public $erreur;
Et le salt doit avoir une portée limitée donc protected ;)

Presque parfait :trollface:

P.S : Tu as oublié de charger ta classe

Bonne journée,
Rivals
 

Walky 🇫🇷

Développeur
Développeur
Inscription
18 Octobre 2012
Messages
1 254
Réactions
1 149
Points
10 840
    Réponse de Walky 🇫🇷 Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #16
P.S : Tu as oublié de charger ta classe
PHP:
$class = new SubmitForm();
:d:

Je ne vois pas comment PhantomJS pourrait "bypass" le formulaire, sachant que si la clé n'est pas valide / non définie, le formulaire ne s'envoie pas (je prends le cas ou les données du formulaire seraient sauvegardées etc..)
 

Rivals

Ancien staff
Premium
Inscription
27 Août 2016
Messages
600
Réactions
498
Points
2 446
    Réponse de Rivals Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #17
PHP:
$class = new SubmitForm();
:d:

Je ne vois pas comment PhantomJS pourrait "bypass" le formulaire, sachant que si la clé n'est pas valide / non définie, le formulaire ne s'envoie pas (je prends le cas ou les données du formulaire seraient sauvegardées etc..)
C'est pas ça charger, ça c'est instancier (tu dois require ton fichier) :d:

PhantomJS te permet de toucher au DOM, donc avoir accès à ton input caché et ainsi on peut faire des boucles :p
 

Walky 🇫🇷

Développeur
Développeur
Inscription
18 Octobre 2012
Messages
1 254
Réactions
1 149
Points
10 840
    Réponse de Walky 🇫🇷 Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #18
C'est pas ça charger, ça c'est instancier (tu dois require ton fichier) :d:
Le code HTML et PHP sont dans le même fichier, donc pas besoin :)

PhantomJS te permet de toucher au DOM, donc avoir accès à ton input caché et ainsi on peut faire des boucles :p
Hum, oui je vois un peu près le fonctionnement :mmh:

Enfin bon, ça permet toujours de sécuriser un minimum ses formulaires, contrairement à un formulaire sans clé.
 

Rivals

Ancien staff
Premium
Inscription
27 Août 2016
Messages
600
Réactions
498
Points
2 446
    Réponse de Rivals Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #19
Le code HTML et PHP sont dans le même fichier, donc pas besoin :)


Hum, oui je vois un peu près le fonctionnement :mmh:

Enfin bon, ça permet toujours de sécuriser un minimum ses formulaires, contrairement à un formulaire sans clé.
Ah d'accord, je pensais que tu séparais les deux, good job :neo:
 

ian 🌊

Membre Premium
Premium
Inscription
7 Novembre 2016
Messages
217
Réactions
68
Points
756
    Réponse de ian 🌊 Forums généraux Informatique ⌨️ Programmation Programmation web : Sécurisez vos formulaires - PHP
  • #20
Lourd merci beaucouè
 


Votre adresse email ne sera pas visible publiquement. Nous ne l'utiliserons que pour confirmer votre message.
Haut