Annonce ToutSurTout

Bienvenue sur toutsurtout.biz

Déjà 15 ans !

Radio TST

Si vous souhaitez participer vous aussi aux discussions sur le forum, il faut vous inscrire ou vous identifier.

Le Thème TST Automne est maintenant en place.

Les inscriptions sont actuellement OUVERTES.

Message 1 Discussion postée le 28-05-2012 à 15:22:26

Loic
Avatar de Loic


Titre: Administrateur d'élite
Avancement: Niveau 5
Lieu: Avec Solenne
Date d'inscription: 26-09-2009
Messages: 107 780
Site web

Sécurisation des failles CSRF

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
?>


http://www.toutsurtout.biz/img/UserBarTST.gif
http://www.toutsurtout.biz/img/Sign-Loic.gif
Loic DL un jour, Loic DL toujours ...