Articles

Le mois de la fonction PHP : protégez-vous des CSRF avec uniqid()

  • Ecrit par Rodolphe Eveilleau
  • vendredi 13 avril 2007
Image pour le titre du contenu

This document is also available in English en 


Dans les applications et les sites Internet, vous avez régulièrement besoin d'identifier une ressource de manière unique. On appelle cela un identifiant.

Il est parfois difficile de générer un identifiant et d'être sûr qu'il soit unique. C'est pour cela que PHP fournit une fonction : uniqid()

Exemple n°1 :


<?php
 
 
   print $identifiant = <a href="http://www.php.net/uniqid">uniqid()</a>;
 
   // Donne 461e5220837d7
 
 
 
 
?>

La variable identifiant contiendra une chaîne de 13 caractères en se basant sur l'heure courante en micro-secondes. Cet identifiant croit légèrement entre deux appels. Comme il change dans le temps, on est assuré qu'il sera toujours unique. Mais il faut savoir renforcer sa predictibilité, en ajoutant un préfixe (premier argument), de l'entropie (deuxième argument). MD5 permet de compléter le blindage.

Exemple n°2 :

<?php
 
 
    $identifiant = md5(uniqid(<a href="http://www.php.net/rand">rand()</a>, true));
 
  // Donne b5a984ae3f11836826325cc5cb6f1c08
 
 
?>

La variable identifiant va maintenant contenir une chaîne de 32 caractères qui sera plus difficile à prédire. Cette méthode est fortement conseillée pour être sûr que l'identifiant généré est unique.

Exemple n°3 :

La génération d'un identifiant unique peut vous permettre de sécuriser vos formulaires contre les CSRF. Le principe est de forcer le chargement unitial du formulaire en y posant un identifiant unique, qui sera vérifié lors de la soumission du formulaire.  L'exemple ci-dessous permet d'écrire des messages dans un fichier (livre d'or, par exemple).

<?php
 
 
    <a href="http://www.php.net/session_start">session_start()</a>;
 
 
    if (isset($_POST['message'])) 
    {
        if (isset($_SESSION['token']) &amp;&amp; $_POST['token'] == $_SESSION['token'])
        {
            $message = htmlentities($_POST['message']);
 
 
            $fp = fopen('./messages.txt', 'a');
            fwrite($fp, "$message<br />");
            fclose($fp);
        }
    }
 
 
    $token = md5(uniqid(<a href="http://www.php.net/rand">rand()</a>, true));
    $_SESSION['token'] = $token;
 
 
?>
 
 
<form action="livre_or.php" method="post">
    <input type="hidden" name="token" value="<?php echo $token; ?>" />
    <input type="text" name="message"><br />
    <input type="submit">
</form>
 
 
<?php
 
 
    readfile('./messages.txt');
 
 
?>

L'identifiant permet dans cet exemple de s'assurer que la personne est bien passé par notre site Internet pour laisser un message.

Cet exemple est extrait du Guide de Sécurité PHP disponible à l'adresse suivante : http://phpsec.org/projects/guide/fr/index.html

Une définition des CSRF est disponible à l'adresse suivante :
http://phpsec.org/projects/guide/fr/2.html#2.4

A mémoriser
  • uniqid() est disponible depuis PHP4
  • En PHP4, uniqid() attend un paramètre en entrée : un préfixe
  • Pour un identifiant uniquement chiffrés, prenez la partie fractionnaire de microtime()
< Précédent   Suivant >

Commentaires

Vous pouvez ajouter votre commentaire!


Vous devez vous connecter pour commenter