Vous n'êtes pas identifié.
Ce script à stocker un jeton unique (clairement une suite de nombres et de lettres) associé à la date d'affichage pour chaque visiteur qui affiche un formulaire dans une session, et ce même jeton dans un champ caché. Ceci permet que la personne qui tente d'exécuter la page est bien passée par le formulaire avant, où on lui a délivré le jeton.
Ce qui donne :
<?php
//On démarre les sessions
session_start();
//On génére un jeton totalement unique (c'est capital :D)
$token = uniqid(rand(), true);
//Et on le stocke
$_SESSION['token'] = $token;
//On enregistre aussi le timestamp correspondant au moment de la création du token
$_SESSION['token_time'] = time();
//Maintenant, on affiche notre page normalement, le champ caché token en plus
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Mon formulaire anti CSRF</title>
</head>
<body>
<form id="form" name="form" method="post" action="traitement.php">
<p>Pseudo :
<label>
<input type="text" name="pseudo" id="pseudo" />
</label>
</p>
<p>E-mail :
<label>
<input type="text" name="email" id="email" />
</label>
</p>
<p>Nom :
<label>
<input type="text" name="nom" id="nom" />
</label>
<input type="hidden" name="token" id="token" value="<?php
//Le champ caché a pour valeur le jeton
echo $token;
?>"/>
</p>
<p>
<label>
<input type="submit" name="Envoyer" id="Envoyer" value="Envoyer" />
</label>
</p>
</form>
</body>
</html>
Ensuite, on passe à la page du traitement, et vous vous rendrez compte qu'il est très simple de se protéger efficacement.
On va déjà vérifier la présence du token, de sa date dans la session, et du token envoyé par POST. Donc, si la personne qui exécute la page n'est pas passée par le formulaire, ça bloque...
Le token doit aussi être valide, c'est-à-dire identique à celui envoyé par POST, et non-expiré, c'est-à-dire que sa génération ne remonte pas à trop longtemps.
Puis on vérifie aussi si le token de $_POST est le même que celui de $_SESSION. Ce qui donne finalement :
<?php
session_start();
//On va vérifier :
//Si le jeton est présent dans la session et dans le formulaire
if(isset($_SESSION['token']) && isset($_SESSION['token_time']) && isset($_POST['token']))
{
//Si le jeton de la session correspond à celui du formulaire
if($_SESSION['token'] == $_POST['token'])
{
//On stocke le timestamp qu'il était il y a 15 minutes
$timestamp_ancien = time() - (15*60);
//Si le jeton n'est pas expiré
if($_SESSION['token_time'] >= $timestamp_ancien)
{
//ON FAIT TOUS LES TRAITEMENTS ICI
//...
//...
}
}
}
//SINON, ON RAJOUTE DES ELSE ET DES MESSAGES D'ERREUR
?>