Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
Bonjour,
Je souhaiterai sécuriser un minimum les sessions de mon application.
Ce que je mets en place :
(temps de session et regeneration de l'id de session)
Zend_Session::rememberMe(260); // temps de validité de la session $defaultNamespace = new Zend_Session_Namespace(); if (!isset($defaultNamespace->initialized)) { Zend_Session::regenerateId(); $defaultNamespace->initialized = true; }
Les validateurs :
J'utilisais des validateur de session pour essayer de securiser un minimum mes session :
Session_Validator_MagicString n'est pas fini donc apres des tests rapide, abandonné (j'ai pas reussi a le finir et qu'il s'initialise corectement).
Zend_Session_Validator_HttpUserAgent mis en place
Session_Validator_RemoteAddr recuperer sur sourceforge -> crash parfois donc abandonné
Ma question :
quel serai l'etat de l'art pour "securiser" un minimum les sessions php sous Zend framework ?
Ce que j'ai mis en place est-il suffisant ?
si vous avez des liens je suis preneur.
Dernière modification par ichevc02 (01-04-2008 11:57:00)
Hors ligne
J'aurai aimé en savoir plus également sur la securité des sessions.
Hors ligne
Bonjour,
je vous fais un retour sur ce que j'ai mis en place.
Je vais avoir un audit securité avant la fin du mois, je pourrai faire un retour sur l'efficacité de ce que j'ai fait :
try{ $newJeton = md5(mktime()); // on peut faire n'importe quoi qui génère un jeton (rand,sha1 ...) IPAB_Session_Validator_MagicString::setKey('UnecleAuChoix'); IPAB_Session_Validator_MagicString::setValue($newJeton); //Zend_Session::registerValidator(new IPAB_Session_Validator_MagicString()); //Registering second validator Zend_Session::start(); Zend_Session::registerValidator(new VotrePackage_Session_Validator_MagicString()); Zend_Session::registerValidator(new Zend_Session_Validator_HttpUserAgent()); Zend_Session::registerValidator(new VotrePackage_Session_Validator_RemoteAddr()); }catch (Exception $e){ //echec soit de l'ouverture de session soit de l'un des validateurs // faire ce qu'il convient. }
j'ai apporté une legeremodification au Zend_Session_Validator_MagicString(); que l'on peut trouvé sur sourceforge :
dans la methode setup du validateur j'ai ajouté
if (!setcookie(self::$magicStringKey, self::$magicStringValue,null,'/' )){ Zend_Registry::get('logger')->log("ECHEC ecriture du cookie ".self::$magicStringKey." => ".self::$magicStringValue , Zend_Log::DEBUG); }
car apparemment le cookie n'était pas écrit, donc le validateur ne fonctionnait pas tel quel.
Zend_Session_Validator_HttpUserAgent() permet de vérifier que le useragent utilisé est le même tout au long de la session.
Session_Validator_RemoteAddr() permet une vérification de l'adresse publique du client tout au long de la session.
Session_Validator_MagicString() permet de détecter le vol de session :
un cookie est placé et la valeur est copiée en session. cette valeur est vérifiée et regénérée à chaque appel.
Si un utilisateur A se fait voler son cookie par un utilisateur B. si B appel le serveur il verra la page et regenerera le jeton dans son cookie ET en session. quand le user A appellera le serveur, la vérification de son jeton échouera (le jeton en session n'est plus le même) ce qui permet de voir que la session à été volée. on détruit la session, donc les 2 utilisateurs devrons se ré-identifier.
remarque sur les validateurs :
Il faut OBLIGATOIREMENT démarrer la session(Zend_Session::strat ou new Zend_Session_Namespace avant les Zend_Session::registerValidator car les validateurs écrivent des données en session justement, donc si elle n'est pas démarrée, les validateurs ne fonctionnerons pas (il n'y aura jamais de vérification).
voila,
si quelqun a mis d'autres choses en place, a des conseils et/ou remarques je suis TRES intéréssé
Dernière modification par ichevc02 (13-05-2008 14:56:36)
Hors ligne
J'essaye d'impleter les MagicString mais je n'y arrive pas, pourrais tu copier coller la classe et son application s'il te plait ?
Et quid de ton audit ?
Dernière modification par Paulop (18-05-2008 21:00:37)
Hors ligne
bonjour,
voici ce que je fais pour Magic string :
tu récupères le validateur a cette adresse :
lien projet sourceforge
tu modifies la methode setup du validateur en ajoutant dedans :
if (!setcookie(self::$magicStringKey, self::$magicStringValue,null,'/' )) { Zend_Registry::get('logger')->log("ECHEC ecriture du cookie ".self::$magicStringKey." => ".self::$magicStringValue , Zend_Log::DEBUG); }
ensuite dans un plugin ou ton bootstrap (// l'endroit ou tu vas démarrer la session)
// penser a faire le loadClass ou le require du validateur.
try{ $newJeton = md5(mktime()); IPAB_Session_Validator_MagicString::setKey('lenomdetoncookie'); IPAB_Session_Validator_MagicString::setValue($newJeton); // il faut le faire avant le register Zend_Session::start(); // il faut le faire avant le register Zend_Session::registerValidator(new IPAB_Session_Validator_MagicString()); //Registering second validator }catch (Exception $e){ // tu passeras ici si l'ouverture de session echoue Zend_Session::destroy();// pour detruire définitivement la session }
il faut setter les valeur avec IPAB_Session_Validator_MagicString::setValue($newJeton); avant le register validator.
si ca te suffit pas je peux t'envoyer mon plugin de gestion de mes sessions (qui est loin d'etre parfait).
pour l'audit, il devrait commencer la semaine prochaine.
Voila.
Dernière modification par ichevc02 (19-05-2008 13:59:45)
Hors ligne
J'aimerai si possible avoir le code de ton plugin et de ta classe IPAB_Session_Validator_MagicString.
J'ai beau essayer je n'y arrive pas
Hors ligne
Bonjour,
Je suis en fin d'audit donc j'ai quelque retours (si ca interesse des gens ):
en ajoutant les validateurs :
- Session_Validator_RemoteAddr() + Session_Validator_HttpUserAgent +Session_Validator_MagicString.
La société n'a pas put usurper une session, donc c'est efficace.
En utilisant les Zend-filter qui vont bien et les db->quote pour les requetes, je n'ai pas eu de soucis d'injection sql ou de code.
J'utilise pour les parametres de navigations des valeurs de session et pas des identifiants de base, pour éviter tout problème.
voila
Hors ligne
Bonjour, ce topic est très très intéressant.
Juste une question : est-ce que la session montée ici est morte à la fermeture du navigateur ?
En fait j'utilise Zend_Session::rememberMe(); qui est très simple, mais quand je vois que beaucoup d'autres solutions sont montées en parallèle, je me dis qu'il n'est peut-être pas vraiment sécurisé.
Donc est-ce que votre solution est équivalente à Zend_Session::rememberMe() au niveau de la durée de vie ?
Hors ligne
une des première chose à faire c'est de changer le nom de la session PHPSESSID car c'est le seul élément qui vas chez le client tout le reste reste sur le serveur
au lieu d'ajouter des truc dans la session pour voir si on a à faire au bon client ce qui nécessite d'ouvrir la session
on peut calculer une clef en fonction du client par exemple
poser un cookie à la première connexion qui génère une clef sur random
utiliser ce cette valeur pour les fois suivantes en y ajoutant la remote adress le user agent et en faire un MD5 ou autre
utiliser ensuite cette valeur comme nom de session à la place de PHPSESSID
ainsi pour ouvrir la session il faut d'abord montrer patte blanche.
alors qu'en ajoutant une clef dans la session il faut d'abord l'ouvrir pour vérifier
le problème avec les sessions c'est qu'on peut éventuellement injecté du code pour ouvrir un fichier de sessions
faut-il encore savoir qui il est et ou le trouver.
tout ce qui peut brouiller les pistes sur c'est accès et bien plus garanti que toute clef placer dans la session
si vraiment il y a gros sur la sécurité on peut alors penser à mettre en place une serialisation dans un session handler qui va utiliser un couple clef publique clef privé pour cripter la session et planquer la clef publique dans un tas d'info inutile dans les header du client.
Il n'y a pas de bonne recette ce qui fait que la sécurité sera efficace c'est la complexité du raisonnement pour accéder à l'info. plus vous serez imaginatif et hors des sentier battus plus un hacker aura de difficulté à passer.
il n'y a donc rien à espérer de la Zend_Lib juste des bout qu'il faut soit-même assembler pour se démarquer de ses voisins.
j'ajoute que en phase de dev je mets souvent plusieurs appli sur le même serveur dans des dossier différents
d'un point de vu PHP il n'y a qu'une session.
en renomment la session j'ajoute au passage dans la clef le nom de l'application ainsi sur un même serveur sans non dns séparé je peux avoir plusieurs appli dans des dossiers différent ayant des sessions différentes
A+JYT
Hors ligne
Ouah, de bon matin c'est hardos pour se concentrer et comprendre.
J'ai tenté un truc tard hier soir mais sans succès :
Quand le visiteur s'identifie sur le site, je génère une clé avec une tambouille md5 + 2/3 autres trucs. Je stocke dans une table la relation : id_membre -> cle_tambouille.
Je balance un cookie sur le navigateur du visiteur identifié avec comme value la clé. Paf, le visiteur se balade tranquillou, et dès que la session PHPSESSID expire (à ce moment là je n'ai pas de RememberMe()), je vérifie s'il y a mon cookie, je récupère la clé, je vérifie si je trouve un ID correspondant (juste que là ça fonctionne), et je recréé une session comme s'il venait de s'identifier, en balançant les mêmes données de cette manière : Zend_Auth_Result(Zend_Auth_Result::SUCCESS,$user,array());
Seulement voilà, le code suivant me retourne false, alors qu'après la "vraie" identification il me retourne true.
$auth = Zend_Auth::getInstance(); $auth->hasIdentity();
Je ne sais pas si ma démarche est correcte ou pas, j'ai très rarement bossé sur des cookies, donc pas vraiment d'expérience là dessus.
Par dépit, hier soir, je me suis tourné vers le RememberMe() mais ça m'a trotté dans la tête toute la nuit, et je veux être certain qu'il y ai un minimum de sécurité.
Hors ligne
Juste une remarque par rapport a ce que j'ai pu ecrire ici sur le remote adresse.
Ca peut poser des problèmes car un user dans une entreprise par exemple, peut venir lors de la même session avec 2 ip différentes.
J'ai du supprimer ce contrôle sur mon Appli.
Pour le nom du cookie de session, je ne suis pas sur d'avoir bien compris.
Je ne vois pas si les valeurs ne change pas à chaque requette comment cela va prémunir du vol d'une session déjà ouverte (je précise que je ne suis pas sur d'avoir bien compris le process expliquer par sekaijin).
tu voles le cookie, t'as gagné, non ?
Dernière modification par ichevc02 (17-09-2008 17:50:04)
Hors ligne
mon propos tiens au fait que pour voler une session la première chose à faire c'est de voler son identifiant.
la première chose que va comprendre un hacker en voyant passer une trame d'un serveur php c'est qu'il s'agit de php car dans l'entêtre de la trame il y a écrit PHPSESSID
sans rien faire Il sais déjà deux information sur le serveur et la session
1 il a à faire à PHP (il peux donc fouiller dans sont stock de failles connues)
2 il connais l'identifiant de la session et peux donc l'exploiter.
en changeant le session_name il voit dans sa trame des headers dont un ou plusieurs sont des clefs, il ne sais pas quelle clef est la bonne et il ne sais pas que c'est un serveur php qui à répondu.
il doit donc arriver à déterminer ces infos avant de pouvoir commencer à attaquer la session.
A+JYT
Hors ligne
Merci pour les précision.
1 il a à faire à PHP (il peux donc fouiller dans sont stock de failles connues)
2 il connais l'identifiant de la session et peux donc l'exploiter.
1) il y a d'autre moyen de trouver si le serveur utilise du php mais c'est clair que c'est mieux de ne pas laisser le phpsessid (ne seraice que s'il y a plusieurs appli sur le même serveur)
2) l'attaquant ne s'embarrasse pas : il prend Tout le cookie et l'utilise, après seulement il sélectionne (enfin je ferai comme ça ;-) )
MagicString pour ne pas lui faire de pub, va lus loin car il permet de détecter le vol de session (si les 2 internautes surf en même temps).
Dernière modification par ichevc02 (18-09-2008 16:52:46)
Hors ligne
Bonjour,
J'ai mis en place tout cela, voilà mon code que j'ai placé dans mon bootstrap:
try { Zend_Session::start(); } catch (Zend_Session_Exception $e) { Zend_Session::destroy(); } Zend_Session::registerValidator(new Zend_Session_Validator_HttpUserAgent()); Zend_Session::registerValidator(new Zend_Session_Validator_MagicString('myKey', 'myValue'));
Aussi, dès que je fais un new Zend_Session_Namespace('quelquechose') dans mon appli, ça plante avec l'erreur suivante :
Missing argument 1 for Zend_Session_Validator_MagicString::__construct()
Que dois-je faire pour résoudre le problème ?
J'ai bien lu, ichevc02, que tu disais qu'il fallait setter les valeurs avant le register, mais est-ce toi qui a ajouté les méthodes setKey() et setValue() ? Car dans la version de Zend_Session_Validator_MagicString que j'ai téléchargé elles n'y sont pas. J'ai bien tenté de les ajouter mais du coup quand je passe le new Zend_Session_Validator_MagicString() au registerValidator() j'ai une erreur car les paramètres sont manquants dans le constructeur.
A moins de refaire toute la classe, et dans ce cas je ne vois plus l'intérêt d'avoir télécharger un truc "prêt à l'emploi", je ne vois pas trop comment faire ?
Merci pour votre aide !
PS : On n'a pas du télécharger la même version car je n'ai pas besoin non plus de compléter la méthode setup()...
Hors ligne
Personne pour me répondre ? :'(
Hors ligne
bonjour,
désolé j'ai pas trop le temps de faire une super réponse donc je vais te copier coller mon magicString,
dis moi s'il te faut plus, j'essaierai de faire mieux dès que j'ai 5 min :
Zend_Loader::loadClass('Zend_Session_Validator_Abstract'); class IPAB_Session_Validator_MagicString extends Zend_Session_Validator_Abstract { static private $magicStringKey ; static private $magicStringValue ; static function setKey($key){ self::$magicStringKey = $key; } static function setValue($value){ self::$magicStringValue = $value; } /** * Setup() - this method will get magic value details provided upon object construction and * will store them for later use * */ public function setup () { //Storing valid data $this->setValidData ( array ( 'key' => self::$magicStringKey , 'value' => self::$magicStringValue ) ) ; //Setting client cookie $_COOKIE [ self::$magicStringKey ] = self::$magicStringValue ; Zend_Registry::get('logger')->log("ecriture du cookie ".self::$magicStringValue , Zend_Log::DEBUG); if (!setcookie(self::$magicStringKey, self::$magicStringValue,null,'/' )){ Zend_Registry::get('logger')->log("ECHEC ecriture du cookie ".self::$magicStringKey." => ".self::$magicStringValue , Zend_Log::DEBUG); } } /** * Validate() - this method will determine if the current user has a cookie with provided name * and value on setup * * @return bool */ public function validate () { $validData = $this->getValidData () ; //Vaidating data against magic value /* ob_start(); var_dump($_COOKIE); var_dump($_SESSION['__ZF']['VALID']); $content = ob_get_contents(); ob_end_clean(); Zend_Registry::get('logger')->log("validation de la passe phrase contenu du cookie : ".$content. "contenu de valide data :".$validData [ 'value' ] , Zend_Log::DEBUG); */ if (isset ( $_COOKIE [ $validData [ 'key' ] ] ) && $_COOKIE [ $validData [ 'key' ] ] === $validData [ 'value' ]) { return true ; } else { return false ; } } }
Dernière modification par ichevc02 (29-10-2008 11:47:33)
Hors ligne
Merci ça fonctionne
Hors ligne
Pages: 1