Bonjour à tous,
J'ai une classe me permettant de générer des "token" pour sécurisé divers appel à des formulaire ou des appels ajax.
Je n'avais jusqu'à maintenant jamais eu de problème. Or je viens de tester la classe sur un hébergement mutualisé et là c'est le drame !
Le concept : On arrive sur un formulaire , un token est généré, stocké en session puis plaer dans un input hidden.
Après soumission du formulaire , je vérifie si le token en session est équivalent à celui passé dans le formulaire.
Le problème : La valeur en session est modifiée entre le clic sur le bouton d'envoi et l'apparition de la page du coup le token n'est jamais le bon.
J'ai retourné le code dans tous les sens mais rien à faire. Un petit exemple simplifié ou je rencontre le problème :
Token.class.php
index.php
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 class Util_Token { static public $error = 0; static public function genToken($ttl = 15) { if(!isset($_SESSION)) throw new Exception("Une session doit être active"); $gentoken = hash('sha1',uniqid(rand(),true)); $rand = rand(1,20); $gentoken = substr($gentoken,$rand,20); $ttl *= 60; $_SESSION['csrf_protect'] = array('token'=>$gentoken,'ttl'=>$ttl); return $gentoken; } static public function checkToken() { if(!isset($_SESSION)) throw new Exception("Une session doit être active"); if($_REQUEST['csrf_protect'] == $_SESSION['csrf_protect']['token']) return true; else return false; } }
En remplacant la chaine aléatoire du token par une date (H:i:s) j'ai remarqué que sur le serveur mutualisé il y'avais 1 sec de décalage entre la date recu et la date en session.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 session_start(); require('Token.class.php'); if(!empty($_POST) || !empty($_GET)) { echo 'Recu Form : '.$_POST['csrf_protect'].'<br />'; echo 'Connu Session : '.$_SESSION['csrf_protect']['token'].' ttl : '.$_SESSION['csrf_protect']['ttl'].'<br />'; } else { $token = Util_Token::genToken(); echo 'Généré : '.$token; ?> <form action="index.php" method="post"> <input type="text" value=" TEst" name="testtext"> <input type="hidden" value="<?php echo $token; ?>" name="csrf_protect"> <input type="submit" value="envoi" /> </form> <?php } ?>
Note : En local je n'ai pas de problème avec ce code...
Partager