- Inscription
- 18 Octobre 2012
- Messages
- 1 268
- Réactions
- 1 187
- Points
- 17 650
-
Réponse de Walky 🇫🇷 Informatique et nouvelles technologies Développement : Sécurisez vos formulaires - PHP
- #1
Bonjour à tous , aujourd'hui nous allons, ensemble, apprendre à sécuriser nos formulaires HTML.
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
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>
Merci @Lawid SEC pour les headers

Walky