Sécurisation d'une session

Sécurisation d'une session - PHP - Programmation

Marsh Posté le 27-02-2005 à 21:52:27    

Bonjour, ce pti post pour un classique problème de sécurité lié aux sessions.
 
Pour identifier des utilisateurs et les laisser connectés tout au long de leur navigation j'utilisais tout simplement une session (sans possibilité de connection automatique c'était voulu).
 
On me dit que cette solution est peu sécurisée car facilement hackable meme par des bots. Et qu'il faut utiliser un triple protocole d'identification : un par session_id, un par cookies, et un par stockage en dure de la session dans la base de données. On m'a aussi dit que c'est comme ca que faisaient les forums en phpbb.
 
D'où mes questions :  
en quoi l'utilisation de session seule est peu sécurisée?
que veut-on dire par stockage de la session dans la base? juste le session_id? toutes les infos de sessions?
 
Merci :)

Reply

Marsh Posté le 27-02-2005 à 21:52:27   

Reply

Marsh Posté le 27-02-2005 à 22:00:22    

A 1ere vue ça me semble qu'au lieu de securiser 1 truc tu ajoutes 2 autres points vulnerables au systeme ... Parcontre faut envoyer le Sid par cookie au client, ça c'est imperatif ...
Parcontre ca m'etonnerais pas que phpbb utilise un truc du genre vu le nombre de prob de secu qu'ils ont :D


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 27-02-2005 à 22:07:21    

oui enfin je voulais dire que je ne créais pas moi meme explicitement de cookies de session, a priori c'est php qui le génère tout seul il me semble non?
 
Et la on me conseille de faire une session, + créer un cookies, + écrire la session en dure dans la base.
 
A priori faire 3 vérifications est plus sécurisée que une seule vérif dans l'absolu non?
 
sinon les questions de mon premier post restent d'actualité  :D


Message édité par Djebel1 le 27-02-2005 à 22:07:52
Reply

Marsh Posté le 27-02-2005 à 22:37:22    

Je n'utilises pas le systéme de session de php mais je vérifies l'identifiant envoyé par le navigateur (contenu dans le cookie) et l'adresse IP du demandeur. Ca limite déjà grandement les risques. Si un jour j'avais besoin de plus de sécurité, je rajouterais l'identifiant du navigateur voire une complication de l'identifaint de session par un rajout de plusieurs caractéres aléatoires.
 
Ca m'étonerait vraiment que les gas qui ont écrit le systéme ne vérifient pas au moins les deux premiéres chôses.

Reply

Marsh Posté le 27-02-2005 à 22:45:04    

Bon deja ton "triple protocole d'identification : un par session_id, un par cookies, et un par stockage en dure de la session dans la base de données." Ne veut rien dire.
 
Il existe deux gros "problemes" lies au sessions et au systeme de "relogin" automatique.
 

Le premier probleme est le fait que les sessions sont stockees sur le disque dur du serveur. Mais que ces dernieres sont accessibles aux autres sites qui sont sur la meme machine. En effet le repertoire ou sont stockees les sessions est commun a tous les sites (dans la plupart des cas).
Donc un site "voisin" pourrais "hacker" tes sessions. Cette possibilité est assez rare, car tu dois etre heberge sur le meme serveur que la personne qui veut te hacker. C'est comme si le voleur qui veut te voler habitais dans ton immeuble ... Pas impossible, mais assez rare.

Afin de "boucher" ce trou, une des solutions retenues la plupart du temps, consiste a stocker les sessions dans ta BDD. Comment ? En creant ton propre "gestionnaire de sessions" que tu vas ensuite declarer a php. Php utilisera ensuite ce gestionnaire pour ton site. Donc grace a ce gestionnaire tu pourras faire ce que tu veux de tes sessions, les stocker dans une BDD, les stocker dans un repertoire specifique a ton site, les crypter, en bref, tu as total control dessus.
 

Le deuxieme probleme concerne l'utilisation du systeme de "relogin" automatique. Avant de venir au coeur du probleme, petite explication sur le processus d'autentification.
La plupart du monde autentifie les utilisateurs de cette maniere.  
Le nom de l'utilisateur et le password "crypte" est stocke dans la BDD. Ensuite lorsque l'utilisateur veut se loguer, il rentre son login puis son password. Ce password est recu non crypte dans la page php. Il est ensuite "crypte" puis on compare les versions "cryptee" des passwords. Si la version cryptee du password correspond a la chaine cryptee qui se trouve dans la base, alors c'est bon, le password est le meme.
 
Maintenant, comment faire pour eviter aux visiteurs de se reloguer a chaque fois ? Ben il suffit de stocker dans un cookie chez le client, son login, puis le password crypte. Comme ca, lorsque le visiteur arrive sur la page, les script  php detectent le cookie, puis comparent le password crypte qui se trouve dans le cookie a celui qui se trouve dans la base de donees. Si c'est le meme, alors c'est bon.
 
Mais voila, il suffit qu'un pirate arrive a acceder a la BDD (grace a une attaque de type "SQL Injection" ) puis il aura access au passwords cryptes. Il pourra les utiliser facilement. Il ne lui suffit que de creer ou "forger" un cookie de "relogin automatique" puis de copier le password crypte. Et voila, en 2-3 mouvement le pirate est logue sur le site. Il ne connait pas le password en lui meme, mais il lui a suffit d'avoir acces au password crypte pour acceder au site.


Malheureusement je ne connais pas de technique efficace pour contrer cette "attaque" si ce n'est "blinder" ses script php ou bien ne pas proposer de "relogin automatique".
 

Il existe egalement un autre probleme. Il existe des script de "brute force" pour essayer de trouver le password de quelqu'un. Ces script ne font qu'essayer des password les uns apres les autres pour essayer de trouver le bon password. Certes c'est long, mais cela peut fonctionner. D'ailleurs il suffit que le script soit un peu plus evolue, par exemple un qui utilise des mots du dicctionnaire et que la personne possede un password simple pour que le script arrive a casser le password


Pour ce genre d'attaques, il y a plusieurs solutions.
Limiter le nombre d'essais dans un laps de temps. Par exemple pas plus de 5 essais en moins de 5 minutes. Cela ne risque pas de gener quelqu'un qui essaye de se rappeler son passoword, mais cela ralentira assez un script.
 
On peut egalement dire aux utilisateurs d'utiliser des password compliques, mais helas, la plupart n'ecouteront pas.
 
Il existe encore une autre technique peu connue (en tout cas je l'ai jamais vue mise en oeuvre). Elle se base sur un "proof of concept" que j'ai vu il y a quelques mois.
La technique se base sur la "biometrie". Vous savez ces appareils qui lisent les empreintes, la retine et compagnie. Vous allez me dire que ce genre d'appareils ne se trouvent pas au coin de la rue. Et pourant je vais vous etonner.
 
La biometrie consiste a "lire" des characteristiques propres a un individue. Cela la plupart du temps, se traduit par l'utilisation d'appareils a la pointe de la technologie... Pourtant, de tels appareils ne sont pas necessaires.
 
Il existe un moyen pour transformer n'importe quel clavier ordinaire en un appareil biometrique. Le principe de base va etre de mesurer le temps que mets l'utilisateur a taper les differentes lettre de son password. Apres un certain temps "d'apprentissage" le script sera cappable de dire si le password rentre etait ecrit par la personne a qui il appartient ou a une autre personne.
 
Quand nous entrons un password au clavier, On ne tappe pas a la meme vitesse les characteres. Par exemple, si l'on prend un mot "javelot" (il necessite les deux mains).  
Personnellement je tape "ja" tres rapidement, ensuite la prochaine letre "v" est un peu plus lente. Puis viens "e" encore un plus lente (meme main). Ensuite "lo" sont assez rapides pour finir avec le "t".
Il suffit que le script "mesure" l'intervale entre chaque lettre un certain nombre de fois pour qu'il puisse en tirer une "moyenne" ainsi que des valeurs maximales et minimales.
 
Ensuite grace a l'utilisation de javascript (je sais, c'est mal), on va pouvoir mesurer le temps lors de la saisie du password. Ces valeurs seront ensuites transmises avec le password. Le script php se chargera ensuite de verifier de un le password, et si ce dernier est correct de verifier les valeurs numeriques qui correspondent aux intervalles des touches. Si ces valeurs rentrent dans les valeurs de tolerance, alors il y a de fortes chances que ce soit la bonne personne.
 
Evidement cette technique n'est pas parfaite :
-Utilisation de javascript
-Phase d'aprentissage pendant laquelle cette "protection" est desactivee.
-Lors du changement de password, la phase d'apprentissage doit de nouveau avoir lieu.
 
En revanche elle a le merite d'etre protegee contre les script de "brute force" ou ceux qui utilisent un dictionnaire.
 
On peut debatre sur l'utilitee de cette methode si les valeurs des intervalles sont "compromises". En effet, un pirate pourrait adapter son script pour que ce dernier "emule" la frape au clavier. Mais pour que cela fonctionne il faut que le pirate connaisse le password, or si le password a ete cryptee dans la BDD, cela est dur. Certes il peut utiliser ces valeurs dans un script "brute force", mais cela va ralentir le script (et si on plus on a prevu des limites, alors le script sera encore plus ralenti).
 
 
 
Voila, j'espere avoir reussi (avec cette longue tirade) a vous montrer que la securitee n'est jamais absolue, qu'il existe des trous, des rustines, mais que rien n'est parfait dans ce bas monde :D

Reply

Marsh Posté le 27-02-2005 à 23:00:50    

Pour la biométrie par mesure de la vitesse de frappe de chaque mot :

  • au fil du temps la vitesse de frappe change ne seraisse que par ce qu'on prend des automatismes au niveau position des doigts.
  • Si on utilise un "nouveau" mot de passe, au fil du temps on apprendra à le taper plus vite.
  • En plus, on peut passer d'une frappe de deux doigts à 3,4 ou 10. (ou l'inverse en cas d'accident)
  • A côté de ça, une coupure à un doigt et c'est le rajout d'un pansement qui va joué sur la facilité de positionement des doigts.


Ces différents événements risquent de faire sortir des intervales de mesures autorisé par le script.
 
Ce n'est donc pas, en pratique, une bonne méthode. C'est donc une fausse bonne idée de sécurisation.
 
EDIT: Et en plus, il faudrait trouver un langage accepté par tout le monde dans leur navigateur et qui permette de mesurer des intervales de saisies, c'est pas gagné.


Message édité par omega2 le 27-02-2005 à 23:05:33
Reply

Marsh Posté le 27-02-2005 à 23:15:00    

@Cerel : merci beaucoup pour cette réponse très précise.  
Visiblement, puisque je suis mon propre hébergeur, l'utilisation d'une session sans proposition de login automatique semble être une bonne solution d'après ce que tu me dis.
 
- Par contre que veux-tu dire par "blinder" ses scripts pour protéger les cookies de reconnection automatique?
 
Sinon, lorque j'utilise une session, je stocke dans $_SESSION['password'] la réelle valeur du password, et non sa valeur cryptée.
 
- Est-ce que cela pose un problème de sécurité? Il ne me semble pas puisque cette variable est stockée coté serveur et donc pas réechanger à chaque fois avec l'utilisateur, mais j'aimerais confirmation svp :)
 
 
questions subsidaires :  
- mais alors quels sont donc ces pbl de hack de variables de session réalisé par des bots ? je ne vois pas où cela pourrait intervenir par rapport aux réponses de Cerel
- et quel intéret de stocker les variables de session dans ta BDD, alors que le serveur le fait dejà pour lui-meme?
 
encore merci


Message édité par Djebel1 le 27-02-2005 à 23:20:44
Reply

Marsh Posté le 27-02-2005 à 23:40:19    

Pour les bruteforce, la meilleure maniere a mon avi, celle que j'utilise et qui est utilisée par ssh, c'est de faire un systeme avec temps exponentiel. En gros 1ere erreur => t'attend 30 sec, 2ème => t'attend 2 min, 3ème => 10min , 4=> 2h ,... Avec un bruteforce qui fait 10'000 erreurs a la seconde, il est bon pour etre banni pendant les 500 prochains millenaires :D


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 28-02-2005 à 00:38:15    

Djebel1 a écrit :

@Cerel : merci beaucoup pour cette réponse très précise.  
Visiblement, puisque je suis mon propre hébergeur, l'utilisation d'une session sans proposition de login automatique semble être une bonne solution d'après ce que tu me dis.
 
- Par contre que veux-tu dire par "blinder" ses scripts pour protéger les cookies de reconnection automatique?


Ce que je veux dire c'est qu'il faut faire en sorte de proteger au maximum les formulaires de saisie, et toutes les variables GET et POST, afin d'eviter qu'un eventuel pirate n'arrive a faire un attaque de type "SQL Injection".
 

Djebel1 a écrit :

Sinon, lorque j'utilise une session, je stocke dans $_SESSION['password'] la réelle valeur du password, et non sa valeur cryptée.

A quoi ca te sert de stocker le password ? Et en clair qui plus est ...  
 

Djebel1 a écrit :


- Est-ce que cela pose un problème de sécurité? Il ne me semble pas puisque cette variable est stockée coté serveur et donc pas réechanger à chaque fois avec l'utilisateur, mais j'aimerais confirmation svp :)
[/quote]En effet c'est cote serveur, et il n'y a pas de "dialogue" avec le client dans le cadre des sessions. Neanmoins, je trouve ca pas tres bon de stocker un password en clair. As-tu reelement besoin de stocker l'edit password ?
 
[quotemsg=995312,7,240190]questions subsidaires :  
- mais alors quels sont donc ces pbl de hack de variables de session réalisé par des bots ? je ne vois pas où cela pourrait intervenir par rapport aux réponses de Cerel

Je ne suis pas sur a quoi tu fais reference, donc je ne peux pas trop repondre a ce sujet. Aurais-tu plus d'infos ?

Djebel1 a écrit :


- et quel intéret de stocker les variables de session dans ta BDD, alors que le serveur le fait dejà pour lui-meme?

Le serveur stocke les sessions dans un repertoire accessible a tout le monde. Le fait de les stocker dans ta BDD va empecher tes sites "voisins" d'y acceder. Tu peux egalement crypter les sessions si tu en as envie, et ca php ne le fait pas de base, mais si tu cree ton propre gestionnaire de sessions, tu pourras le faire.

Djebel1 a écrit :

encore merci


Faut surtout que tu te rende comptes que rien n'est a 100% securise.  
Dans toute la chaine pour le login, il peut toujours y avoir un maillon insoupçone  qui lache, et ce n'est pas toujours le meme...  
Par exemple, il peut y avoir une faille sur le serveur mail installe sur la meme machine, cette faille peut conduire a l'execution d'un code arbitraire qui permet au pirate d'executer un "root kit", il aura ainsi un access admin au serveur.
Il peut par exemple y avoir une faille dans php qui fait qu'apache va simplement "afficher" le code php sans "l'executer". Du coup le pirate pourra voir le code source, l'analyser et en sortir les failles beaucoup plus facilement.

Reply

Marsh Posté le 28-02-2005 à 01:24:02    

cerel a écrit :

Ce que je veux dire c'est qu'il faut faire en sorte de proteger au maximum les formulaires de saisie, et toutes les variables GET et POST, afin d'eviter qu'un eventuel pirate n'arrive a faire un attaque de type "SQL Injection".


tu veux dire faire de bonnes vérifications au niveau de ce qui est entré par l'utilisateur? du genre restreindre certains symboles etc? (enfin si cette question te saoule j'irai me renseigner sur le "SQL injection" :) )
 

cerel a écrit :

A quoi ca te sert de stocker le password ? Et en clair qui plus est ...


il s'agit d'une interface PHP réservé à un groupe d'utilisateurs restreints (définis par leurs login et pass MySQL) afin d'entrer dans la base elle-même de nouvelles données, j'utilise donc un mysql_connect avec les $_SESSION['login'] et $_SESSION['password']. S'il y a un autre moyen je le connais pas  :(
[EDIT]ou alors, en définissant une autre table de log/pass dans la base, et si l'utilisiteur est identifié dans cette table, alors le script lui confere les droits MySQL d'insérer des données dans la base. Dans ce cas plus besoin de stocker le pass en clair dans une variable de session, mais un password MySQL sera indiqué en clair sur le code source PHP. Je ne sais pas lequel des 2 est le plus sécurisé, si jamais tu en as une idée ;)
[/EDIT]

cerel a écrit :

Je ne suis pas sur a quoi tu fais reference, donc je ne peux pas trop repondre a ce sujet. Aurais-tu plus d'infos


non, je discutais avec quelqu'un qui gère un forum PHPBB. Après avoir expliqué que sa table de session avait explosé car site trop fréquenté, je lui ai demandé à quoi servait de stocker dans la BDD les sessions, il m'a répondu que c'était facilement hackable par des bots, ca doit rejoindre ton problème d'enregistrement des sessions sur un répertoire commun
 
 
En conclusion, la solution de passer uniquement par les variables de session, sachant que je suis mon propre hébergeur (donc pas de partage de session), malgré le fait que l'une d'entre-elle stocke le password en clair, cela te parait-il relativement satisfaisant?


Message édité par Djebel1 le 28-02-2005 à 01:27:54
Reply

Marsh Posté le 28-02-2005 à 01:24:02   

Reply

Marsh Posté le 28-02-2005 à 19:22:15    

pti up au cas où Cerel avait pas vu le message :D

Reply

Marsh Posté le 28-02-2005 à 20:50:24    

Djebel1 a écrit :

tu veux dire faire de bonnes vérifications au niveau de ce qui est entré par l'utilisateur? du genre restreindre certains symboles etc? (enfin si cette question te saoule j'irai me renseigner sur le "SQL injection" :) )


Oui en effet, il faut controler ce que rentre l'utilisateur. Donc faire attention aux ' et aux ", mais egalement au type de donnees. Si tu as un formulaire ou l'utilisatuer doit rentrer un chiffre, mais que tu recois du texte ...
Si tu veux "bien" faire, faut prendre comme "hypothese de depart" que le mec est un pirate. Donc tu dois absolument tout controler. Autre hypothese sympa "si l'utilisatuer peut faire une connerie, alors il la fera". :D
 

Djebel1 a écrit :


il s'agit d'une interface PHP réservé à un groupe d'utilisateurs restreints (définis par leurs login et pass MySQL) afin d'entrer dans la base elle-même de nouvelles données, j'utilise donc un mysql_connect avec les $_SESSION['login'] et $_SESSION['password']. S'il y a un autre moyen je le connais pas  :(
[EDIT]ou alors, en définissant une autre table de log/pass dans la base, et si l'utilisiteur est identifié dans cette table, alors le script lui confere les droits MySQL d'insérer des données dans la base. Dans ce cas plus besoin de stocker le pass en clair dans une variable de session, mais un password MySQL sera indiqué en clair sur le code source PHP. Je ne sais pas lequel des 2 est le plus sécurisé, si jamais tu en as une idée ;)
[/EDIT]


Bon cela m'a l'air d'un cas exceptionnel. Donc a la limite, dans ce cas la ok, tu pourrais stocker le pass en clair (car du dois le reutiliser). Mais faut eviter que cela ne devienne une habitude :D
 

Djebel1 a écrit :


non, je discutais avec quelqu'un qui gère un forum PHPBB. Après avoir expliqué que sa table de session avait explosé car site trop fréquenté, je lui ai demandé à quoi servait de stocker dans la BDD les sessions, il m'a répondu que c'était facilement hackable par des bots, ca doit rejoindre ton problème d'enregistrement des sessions sur un répertoire commun


J'ai pas d'infos a ce sujet, desole :/
 

Djebel1 a écrit :


En conclusion, la solution de passer uniquement par les variables de session, sachant que je suis mon propre hébergeur (donc pas de partage de session), malgré le fait que l'une d'entre-elle stocke le password en clair, cela te parait-il relativement satisfaisant?


 
Si tu es ton propre hebergeur, alors tu elimines certes un trou potentiel. Mais il ne faut pas te croire a l'avris... Il peut y avoir un trou dans un autre programme installe sur ta machine que tu as oublie de patcher...
 
Pour finir, oui l'utilisation d'une session comme tu l'a decrites pourrait tenir la route, mais je te conseille quand meme de te renseigner sur la creation de ton gestionnaire de sessions afin de stocker les sessions dans ta BDD.
Et puis meme si les utilisateurs doivent rentrer un login valide de la BDD, rien ne t'empeche d'avoir un autre login pour les access a la base qui ne dependent pas de l'utilisateur logue.

Reply

Marsh Posté le 28-02-2005 à 23:22:47    

ok merci bcp pour tous ces conseils
 

cerel a écrit :

Et puis meme si les utilisateurs doivent rentrer un login valide de la BDD, rien ne t'empeche d'avoir un autre login pour les access a la base qui ne dependent pas de l'utilisateur logue.


 
 
un peu comme je le proposais dans mon [edit] non? mais dans ce cas le log et pass pour les acces à la base sont stockés en clair dans la source PHP, je sais pas ce qui est le mieux. Bon allez je m'en vais potasser tout ca :D

Reply

Marsh Posté le 04-03-2005 à 16:16:06    

cerel a écrit :


Le deuxieme probleme concerne l'utilisation du systeme de "relogin" automatique. Avant de venir au coeur du probleme, petite explication sur le processus d'autentification.
La plupart du monde autentifie les utilisateurs de cette maniere.  
Le nom de l'utilisateur et le password "crypte" est stocke dans la BDD. Ensuite lorsque l'utilisateur veut se loguer, il rentre son login puis son password. Ce password est recu non crypte dans la page php. Il est ensuite "crypte" puis on compare les versions "cryptee" des passwords. Si la version cryptee du password correspond a la chaine cryptee qui se trouve dans la base, alors c'est bon, le password est le meme.
 
Maintenant, comment faire pour eviter aux visiteurs de se reloguer a chaque fois ? Ben il suffit de stocker dans un cookie chez le client, son login, puis le password crypte. Comme ca, lorsque le visiteur arrive sur la page, les script  php detectent le cookie, puis comparent le password crypte qui se trouve dans le cookie a celui qui se trouve dans la base de donees. Si c'est le meme, alors c'est bon.
 
Mais voila, il suffit qu'un pirate arrive a acceder a la BDD (grace a une attaque de type "SQL Injection" ) puis il aura access au passwords cryptes. Il pourra les utiliser facilement. Il ne lui suffit que de creer ou "forger" un cookie de "relogin automatique" puis de copier le password crypte. Et voila, en 2-3 mouvement le pirate est logue sur le site. Il ne connait pas le password en lui meme, mais il lui a suffit d'avoir acces au password crypte pour acceder au site.


Malheureusement je ne connais pas de technique efficace pour contrer cette "attaque" si ce n'est "blinder" ses script php ou bien ne pas proposer de "relogin automatique".


 
J'ai utilisé sur un de mes sites une méthode qui permet au moins d'éviter ce problème.
Lorsque l'utilisateur s'est connecté avec succès en utilisant son login et son mot de passe, il se voit attribuer un numéro de ticket (chaîne de caractères longue et aléatoire, assez longue pour être supposée impossible à deviner).
Ce numéro de ticket est stockée dans un cookie de login automatique. En base de données, on ajoute un enregistrement qui associe le ticket à un utilisateur (ainsi qu'un hash de son IP et un hash de son useragent).
Lorsqu'un utilisateur non connecté revient sur le site:
- je purge les vieilles infos de connexion automatique
- je regarde s'il a un cookie de connec automatique
- je vérifie si le numéro de ticket est valide et que l'IP et l'UA concordent (vu que  
l'information provient d'un cookie, il n'y a pas de raison que l'UA ait changé)
- si tout est bon je log le mec
 
C'est toujours contournable, mais un plus pénible à contourner qu'une simple attaque par piquage de hash de password.


---------------
Loose Change Lies | Bars | Last.fm
Reply

Marsh Posté le 04-03-2005 à 16:29:53    

oui mais si le pirate a acces au hash du password par SQL injection, il doit avoir acces au reste pitetre? (je me susi pas encore documenté sur la SQL injection :D)
SI il a acces au reste, il doit pas avoir de mal a récupérer l'IP et l'UA dans la base j'imagine (enfin comme d'hab, mes dires se basent sur du vent :) )

Reply

Marsh Posté le 04-03-2005 à 16:50:58    

C'est pas dur de se protéger contre les injections SQL quand même :D

Reply

Marsh Posté le 04-03-2005 à 16:58:16    

Djebel1 a écrit :

oui mais si le pirate a acces au hash du password par SQL injection, il doit avoir acces au reste pitetre? (je me susi pas encore documenté sur la SQL injection :D)
SI il a acces au reste, il doit pas avoir de mal a récupérer l'IP et l'UA dans la base j'imagine (enfin comme d'hab, mes dires se basent sur du vent :) )


 
Une fois qu'il a le ticket, le hash de l'IP et le hash de l'UA, il fait quoi l'attaquant ?  
Il n'a pas idée de la fonction de hash utilisée. Pour faire chier j'ai très bien pu utiliser un md5 maison. Dans ce cas il ne retrouvera jamais la bonne IP, ni un UA compatible. Le script va le jeter s'il forge un cookie d'autoconnexion et qu'il tente son attaque.
 
Deuxième point, le ticket est invalidé s'il y a tentative d'autologin avec IP/UA qui ne concordent pas. Résultat, il n'a plus qu'à attendre que l'utilisateur légitime se reconnecte, à ré-exploiter son injection SQL, et... retenter sa manip.


---------------
Loose Change Lies | Bars | Last.fm
Reply

Marsh Posté le 04-03-2005 à 17:17:36    

ratibus a écrit :

C'est pas dur de se protéger contre les injections SQL quand même :D


 
Va le dire a phpbb :D
 
 
Kriscool : Le probleme c'est qu'une ip sa change plus qu'un UA, enfin ca depends de la connexion. Et un UA ca peut se trafiquer.


Message édité par cerel le 04-03-2005 à 17:21:28
Reply

Marsh Posté le 04-03-2005 à 17:38:28    

cerel a écrit :

Va le dire a phpbb :D
 
 
Kriscool : Le probleme c'est qu'une ip sa change plus qu'un UA, enfin ca depends de la connexion. Et un UA ca peut se trafiquer.


 
Oui pour les deux.
L'UA ça peut se trafiquer, mais si tu dois trouver l'UA qui une fois passé à la moulinette d'une fonction de hash que tu ne connais pas, doit donner une chaîne que tu connais, bah je dirais que tu est bien avancé :D


---------------
Loose Change Lies | Bars | Last.fm
Reply

Marsh Posté le 04-03-2005 à 21:03:51    

Faut deja passer tout ce qui rentre au addslashes, ou a la limite j'ai vu une fonction ... je sais plus le nom... qui rend une chaine conforme au format SQL ... Donc a premiere vue ca peut securiser contre les injections SQL, du moins le genre qu'on presente sur php.net


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 05-03-2005 à 05:03:22    

limite les magic quotes font l'affaire en gros?

Reply

Marsh Posté le 05-03-2005 à 07:22:32    

Mieux vaut prevoir un script qui marchera avec ou sans magic-quote que faire un site moulé sur une config


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 05-03-2005 à 10:42:21    

ou alors changer la conf des magic quotes via un ini_set... ça t'évite de foutre des addslashes partout mais tu est ok sur toutes les confs paske tu les adapte à ton script ;)


---------------
- Xav - ...There are no crimes when there are no laws... -- Xav's World
Reply

Marsh Posté le 08-03-2005 à 10:17:06    

esox_ch a écrit :

Faut deja passer tout ce qui rentre au addslashes, ou a la limite j'ai vu une fonction ... je sais plus le nom... qui rend une chaine conforme au format SQL ... Donc a premiere vue ca peut securiser contre les injections SQL, du moins le genre qu'on presente sur php.net


 

Xav_ a écrit :

ou alors changer la conf des magic quotes via un ini_set... ça t'évite de foutre des addslashes partout mais tu est ok sur toutes les confs paske tu les adapte à ton script ;)


 
Pour être plus adapté à toutes les confs, je pense que le mieux est d'utiliser des objets "adaptateurs", vous accéder à sa base de données où aux autres fonctions sensibles.
 
Pour mon site, je ne fais aucune requête directement. J'ai recodé un truc similaire aux "prepared statements" de PHP 5. Dans mon code, mes requêtes sont du genre 'SELECT * FROM %t WHERE champ=%i', et j'utilise une fonction de remplacement pour composer la requête, en échappant proprement les paramètres.
 
Ca me permet de faire les adaptations suivantes, selon le besoin
- transformation d'une valeur null en chaîne 'NULL'
- transformation d'une chaîne vide en chaîne 'NULL'
- vérification qu'un entier est bien un entier
- échappement des chaînes de caractères
- conversion de dates
- etc.
 
Une sorte de printf quoi.
Via cette classe, je peux également tenir un "log" des requêtes effectuées, ce qui aide bien au débug, et faire encore pas mal de choses dans le style.  
Après il me suffit de n'utiliser que cette classe pour les requêtes, ce qui me permet:
- de ne plus avoir à me préoccuper de la connexion à la base
- de ne plus avoir à faire attention aux valeurs des variables que j'inclus dans mes requêtes
 
De plus, s'il s'avère que j'ai omis une vérification de sécurité sur un type de variables dans ma classe, je n'ai que cette classe à modifier.
 
Maintenant, c'est ma façon perso d'avoir fait les choses. Entre autres parce que je n'avais pas accès à PEAR DB. Si c'était à refaire, je me taperais pas tout moi même à la main :)


---------------
Loose Change Lies | Bars | Last.fm
Reply

Marsh Posté le 08-03-2005 à 10:18:46    

Je viens de retrouver le nom de la fonction :  
 
mysql_real_escape_string() , ça a l'air pas mal


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 10-03-2005 à 03:37:11    

ha ouais effectivement ca a l'air sympa, merci de l'info

Reply

Marsh Posté le 21-03-2005 à 01:49:41    

lu tlm!
 
 
juste 2-3 ptites choses basées sur ces interventions intéressantes:
 
- même via un init_set(), est-ce que ça marche bien le magic_quote ? Je connais que le côté "applicatif" (le front-office n'est-ce pas..) d'Apache, et du coup g po forcément confiance, mais je sais po si c'est à tort ou à raison  :whistle:  
 
- @Kriscool: de toute facon la vérification de cohérence & d'intégrité des données doit toujours se faire avant insertion dans la base.. Là tu l'as faite en objet, c'est sûr que c'est + pratique et + beau :D Ou alors j'ai po bien compris :??:  
 
- @esox_ch: mysql_real_escape_string() :jap: Juste: ça prend en compte le jeu de caractères courant.. Ya po de risque de pouvoir créer des correspondances avec d'autres caractères si jamais on modfiait ce jeu :??:  
 
Sinon c intéressant les sujets sur la sécurité (surtout logicielle), ça rassure un peu..  [:alph-one]  :D

Reply

Marsh Posté le 21-03-2005 à 08:08:34    

>LKoLRn : Le ini_set() n'a pas d'influence sur le magic_quote malgres ce que beaucoup de personnes pensent, va voir sur www.php.net et tu le verras.
 
Et je comprends pas ce que tu veux dire par ton truc des caracteres


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 21-03-2005 à 14:28:59    

lkolrn a écrit :

- @Kriscool: de toute facon la vérification de cohérence & d'intégrité des données doit toujours se faire avant insertion dans la base.. Là tu l'as faite en objet, c'est sûr que c'est + pratique et + beau :D Ou alors j'ai po bien compris :??:


 
C'est pas plus beau, c'est juste ma méthode à moi pour grouper les différentes vérifications à un seul endroit bien défini du code, pour pas avoir à me les retaper partout.  :hello:  


---------------
Loose Change Lies | Bars | Last.fm
Reply

Marsh Posté le 21-03-2005 à 18:06:53    

ui, c de l'objet...
 
 
@esox_ch: cette fonction avec les directives magic_quotes_* ne fonctionne po :??: Faut forcément aller modifier le fichier en dur alors ?? :sweat:
 
ps: pour le jeu de caractères, g dis une connerie.. :o


Message édité par lkolrn le 21-03-2005 à 18:09:47
Reply

Marsh Posté le 21-03-2005 à 20:52:53    

lkolrn a écrit :

ui, c de l'objet...
 
 
@esox_ch: cette fonction avec les directives magic_quotes_* ne fonctionne po :??: Faut forcément aller modifier le fichier en dur alors ?? :sweat:
 
ps: pour le jeu de caractères, g dis une connerie.. :o


 
Exact, ou alors tu fais ca proprement => tu fais une fonction qui detecte si c'est on ou off et strip/add les slashs en consequence


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 22-03-2005 à 07:54:37    

Un truc dans le genre :

Code :
  1. function unescape($str) {
  2.     return get_magic_quotes_gpc() ? stripslashes($str) : $str;
  3. }

Reply

Marsh Posté le 29-03-2005 à 17:18:41    

Par rapport à la méthode que j'utilise pour identifier les utilisateurs (traités plus haut donc), je voulais votre opinion sur une solution alternative, pour savoir ce qui d'après vous est le "moins pire" :
 
- Solution actuellement utilisée : étant donné que les utilisateurs doivent pouvoir modifier la base SQL en elle-même, leurs logins et pass sont ceux de la base elle-même. Le pass est stocké en clair dans une variable de session, afin qu'un utilisateur identifié puisse faire les insert, delete, update, etc.
 
- Solution alternative : je peux également utiliser une table de logins dans la base de données ; quand un utilisateur se connecte, on va voir dans cette table si son login et pass sont valides (jusque la classique) et on vérifie son niveau de privilèges.
En fonction de son niveau de privilège, le script PHP utilisera alors un login et pass adapté, et contenu dans le script.  
Concrètement on aurait donc une série de logins et pass dans le script PHP.
 
D'après vous quelle est la meilleure solution? (bien sur si vous en avez d'autres je prends ^^)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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