Petite vérif sur mon script de session, svp ?

Petite vérif sur mon script de session, svp ? - PHP - Programmation

Marsh Posté le 01-06-2004 à 12:25:25    

Bonjour à tous,
 
voilà, je vous soumet mon script d'identification de session (enfin une partie). Ca fonctionne bien, je n'ai pas de pb dans l'utilisation quotidienne mais il y a 2 p'tits trucs qui me chagrinent  :D  
 
1) Au niveau sécurité, est-ce que le script présente des aberrations, est-ce que c'est à peu près propre et un poil optimisé ?
 
2) j'ai 2 fois la mention "session_start();", est-ce que ça peut gêner ?  
 
Merci de vos contribs. Même si ça tourne, ça ne veut pas dire que c'est bien codé  :pt1cable:  
 
Voici le ch'tit script :
 

Code :
  1. <?
  2. session_start();
  3. if (session_is_registered('identifiant'))
  4. {
  5.    // déjà connecté...
  6.    header('location: console.php?' .session_name(). "=".session_id());
  7. }
  8. // si le formulaire a été validé
  9. $test = (isset($_POST['action'])) ? $_POST['action'] : Null;
  10. if ($test)
  11. {
  12.   include('connect.php');
  13.   $query_admin = "SELECT * FROM admin";
  14.   $result_admin = mysql_query($query_admin);
  15.   /* On récupère le nombre d'enregistrements */
  16.   $nb = mysql_numrows($result_admin);
  17.   // On récupère les valeurs du formulaire
  18.   $log_admin = $_POST['identifiant'];
  19.   $pass_admin = $_POST['mdp'];
  20.   // On vérifie si le login existe dans la table
  21.   while ($val = mysql_fetch_array($result))
  22.   {
  23.            $login_table = $val["login"];
  24.            $password_table = $val["password"];
  25.            if ($login_table == $log_admin && $password_table == $pass_admin)
  26.            {
  27.                   // Si les password et login sont valides
  28.                 session_start();   // on démarre une session
  29.                   // On enregistre les variables login et
  30.                 // password dans la session en cours
  31.                 $_SESSION['identifiant'] = $log;
  32.                 $_SESSION['mdp'] = $pass;
  33.                  //Redirection sur une page pour afficher le résultat
  34.                 mysql_close();
  35.                 header('location: console.php?' .session_name(). "=".session_id());
  36.         }
  37.   }
  38.   // Si on sort de la boucle : l'identification a échouée
  39. mysql_close();
  40. header('location: auth_fail.php');
  41. // Fin du traitement après validation du formulaire
  42. ?>
  43. ... ici c'est la partie contenant le formulaire


 
 :jap:  :jap:  
 :hello:

Reply

Marsh Posté le 01-06-2004 à 12:25:25   

Reply

Marsh Posté le 01-06-2004 à 12:31:36    

Pas la peine de lire toute la table admin...
Vérifie en premier que $log_admin ne contienne que dé caractères autorisés et en nombre correct (via un regexp par exempel), et ensuite tu fais une requête avec un where sur le login. Si t'es parano, avant de vérifier le MDP, tu vérifie que la requête te retourne exactement 1 enregistrement.
Rmq: Tu peux aussi vérifier le MDP via une regexp...


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 01-06-2004 à 12:41:03    

:jap:  
 
merci pour tes conseils, je vais implémenter ça
 
Pour les regex, je ne connais pas très bien, je vais me documenter là-dessus  ;)  
 
 :hello:

Reply

Marsh Posté le 01-06-2004 à 12:42:50    

Te plantes pas sur les regexp !
Si tu donne tes règles pour login et mdp, on doit pouvoir t'aider :D


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 01-06-2004 à 12:44:58    

ok  :)  
 
Pour les identifiants login & password, je n'ai pas de règles précises, excepté que les 2 ne doivent pas excéder 10 caractères. Qu'est-ce que je pourrais définir comme règles ?

Reply

Marsh Posté le 01-06-2004 à 12:52:01    

Par exemple interdire les espaces, les ', les " ...
 
Demander un minimum de caractères pour login et mdp genre 6 ou 8
 
Pour le login, on a tendance à autoriser les chiffres, et les lettres non accentuée en minuscule et majuscule et à demander à ce que la chaîne commence par une lettre.
 
Pour le mdp, on autorise tout sauf ' et " qui peuvent poser problème. Mais on peux aussi les autoriser si on fait très très attention à ce qu'on fait :D


Message édité par Mara's dad le 01-06-2004 à 12:52:35

---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 01-06-2004 à 13:00:46    

ah oui, tiens, c'est pas bête ça  :)  
 
donc pour les login/password, on peut interdire les espaces les ' et les "
On met les 2 à 8 caractères minimum et on interdit les caractères accentués dans le login. Ca me vas très bien ça  :jap:  

Reply

Marsh Posté le 01-06-2004 à 13:03:16    

Mais c'est vraiment du luxe quand même puisque l'admin, il n'y en a qu'un en principe et c moi !

Reply

Marsh Posté le 01-06-2004 à 13:15:33    

n'oublie pas de faire un exit après un header('Location: ....'); car sinon ça continue à s'exécuter :)

Reply

Marsh Posté le 01-06-2004 à 14:23:33    

ratibus a écrit :

n'oublie pas de faire un exit après un header('Location: ....'); car sinon ça continue à s'exécuter :)


 
 :jap:

Reply

Marsh Posté le 01-06-2004 à 14:23:33   

Reply

Marsh Posté le 01-06-2004 à 14:25:25    

Juste une question : pour les regexp, ça se fait au niveau de php ou bien avec le REGEXP de MySQL ?
 
Ah oui, et un petit détail : pourquoi tester la saisie de l'utilisateur lors de l'identification et non pas plutot simplement de regarder si on trouve l'équivalence avec un enregistrement dans la bdd ? la vérification de la saisie, c'est plutot lorsque l'utilisateur s'inscrit, non ?  :??:  
 
Et pour le fait que "session_start" apparaisse 2 fois (selon les cas la fonction session_start pourra être appelée 2 fois), ça ne cause pas de souci ?


Message édité par juanetfanny le 01-06-2004 à 14:40:37
Reply

Marsh Posté le 02-06-2004 à 12:33:27    

up

Reply

Marsh Posté le 02-06-2004 à 12:56:22    

tout ce que tu peux faire au niveau sql est à faire... donc fais le REGEXP dans la requête directement : c plus rapide en temps (pas beaucoup il est vrai :))

Reply

Marsh Posté le 02-06-2004 à 13:27:27    

Le deuxième session start ne sert à rien.
 
On teste la saisie de l'utilisateur par une regexp en PHP avant de l'utiliser dans une requête SQL.
 
POURQUOI ?
 
Pour éviter les problèmes "d'injection SQL".
 
Exemple de requete :
 
"select * from page where page_id=$p"  
 
Si $p est une valeur saisie par l'utilisateur ou un lien avec la variable visible, l'utilisateur peut faire ce genre de choses :
p=1; drop table page;
 
alors la requête devient:  
"select * from page where page_id=1; drop table page;"  
 
Amusant non ?
 
Conclusion, AVANT d'utiliser une valeur venant du client (le browser) il faut la vérifier.
 
Dans l'exemple, on attend une valeur pour $p. Cette valeur doit être un nombre, ce qui DOIT être vérifié AVANT d'utiliser $p dans une requête. Il est même conseillé de vérifier que $p est bien dans une fourchette de valeurs acceptables. M'enfin là on frise la paranoïa... Mais il est toujours possible d'imaginer que si :
$p=1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
Alors sait-on jamais, ça peut par exemple faire planter PHP ou le serveur de base de données...
 
Bref, il ne faut pas faire confiance au client. Jamais !
 
Donc pour le user, on vérifie par regexp que la valeur fournie est compatible avec les règles de gestion ET qu'elle est utilisable sans danger dans une requête SQL.
 
Pour te simplifient la vie, tu peux par exemple écrire une fonction générique de vérification à mettre dans un fichier php à inclure un peu partout.
 
check.php

Code :
  1. <?php
  2. $reginfo[ "USER_LOGIN" ] = "/^[a-z]{1,1}[0-9a-z]{5,9}$/i"; // Chaîne de 6 à 10 caractères (lettre minuscule ou majuscule ou chiffre) commençant par une lettre.
  3. $reginfo[ "ADMIN_LOGIN" ] = "/^[a-z]{1}[0-9a-z]{7,11}$/i"; // Chaîne de 8 à 12 caractères (lettre minuscule ou majuscule ou chiffre) commençant par une lettre.
  4. $reginfo[ "DATE_JJ/MM/AAAA" ] = "/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/"; // Date au format JJ/MM/AAAA,  ne garantie pas la validité de la date.
  5. $reginfo[ "NUMBER" ] = "[0-9]{1,10}"; // Nombre de 1 à 10 chiffres
  6. $reginfo[ "EMAIL" ] = "/^[\w_.-]+@[\w_.-]+\\.[\w]+$/"; // Email
  7. function checkInput( $input, $format )
  8. {
  9. global $reginfo;
  10. return( preg_match( $reginfo[ $format ], $input ) > 0 );
  11. }
  12. ?>


Message édité par Mara's dad le 02-06-2004 à 13:27:47

---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 02-06-2004 à 14:44:26    

(pitit drapeau discret)


---------------
oui oui
Reply

Marsh Posté le 02-06-2004 à 19:55:31    

Mille fois :jap:  Mara's Dad !
 
C'est sympa de t'être penché sur mon script et d'avoir apporté une excellente contribution.  
 
Encore  :jap:  
 
 :hello:

Reply

Marsh Posté le 02-06-2004 à 21:15:18    

J'aime PHP, la sécurité, la bonne utilisation des sessions et les regexp ... entre autre :D
Alors t'as juste de la chance que je passe une peu de temps sur le forum en ce moment :)


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 02-06-2004 à 23:40:10    

Mara's dad a écrit :

Le deuxième session start ne sert à rien.
 
On teste la saisie de l'utilisateur par une regexp en PHP avant de l'utiliser dans une requête SQL.
 
POURQUOI ?
 
Pour éviter les problèmes "d'injection SQL".
 
Exemple de requete :
 
"select * from page where page_id=$p"  
 
Si $p est une valeur saisie par l'utilisateur ou un lien avec la variable visible, l'utilisateur peut faire ce genre de choses :
p=1; drop table page;
 
alors la requête devient:  
"select * from page where page_id=1; drop table page;"  
 
?>[/cpp]


 
perso pour eviter qq soucis en ce qui concerne ma navigation moi j'utilise un Switch/case comme ca par default si y a un truc louche je le sais -> page defaut et je le retourne la ou il faut !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed