Sessions et sécurité

Lien externe : » Session fixation

La gestion des sessions HTTP est au coeur de la sécurité sur le Web. Des mesures d'atténuation doivent être prises en compte afin d'assurer la sécurité des sessions. Les développeurs doivent activer/utiliser les paramètres de configuration appropriés.

  • session.cookie_lifetime=0. La valeur 0 a une signification spéciale. Elle indique aux navigateurs de stocker les cookies dans un stockage permanent. Toutefois, lorsque le navigateur se ferme, le cookie contenant l'ID de session est supprimé immédiatement. Si le développeur définit une valeur différente de 0, il peut permettre à d'autres utilisateurs d'utiliser l'ID de session. La plupart des applications doivent utiliser 0 pour cette option. Si l'auto-identification est nécessaire, implémentez votre propre fonctionalité d'auto-identification sécurisée. N'utilisez surtout pas l'ID de session pour cela.
  • session.use_cookies=On et session.use_only_cookies=On. Malgré le fait que les cookies HTTP ont quelques problèmes, ils restent la façon privilégiée de gérer l'ID de session. N'utilisez que les cookies pour la gestion de l'ID de session lorsque c'est possible. La plupart des applications utilisent le cookie pour l'ID de session.
  • session.use_strict_mode=On. Cette option empêche le module de session d'utiliser un ID de session non initialisé. Dans d'autres termes, le module de session n'acceptera qu'un ID de session valide généré par le module de session. Il rejètera un ID de session fourni par les utilisateurs. Un injection d'ID de session peut être réalisé par un injection de cookie via Javascript de façon permanente ou temporaire. Lorsque la transparence de session est actif, l'ID de session peut être injecté via une chaîne de requête ou un paramètre de formulaire. Il n'y a aucune raison d'accepter un ID de session fourni par l'utilisateur, la plupart des applications ne doivent pas accepter des ID de session non initialisés fournis par l'utilisateur.
  • session.cookie_httponly=On. Désactive l'accès au cookie de session par Javascript. Cette option évite le vol de cookie par injection Javascript. Il est possible d'utiliser l'ID de session comme clé de protection CSRF, mais ce n'est pas recommandé. Par exemple, le source HTML peut être sauvegardé puis envoyé à d'autres utilisateurs. Pour une meilleure sécurité, le développeur ne doit pas écrire l'ID de session dans une page Web. La plupart des applications doivent utiliser l'attribut httponly pour le cookie contenant l'ID de session.
  • session.cookie_secure=On. Autorise l'accès au cookie contenant l'ID de session lorsque le protocole est HTTPS. Si votre site Web est un site Web uniquement accessible via HTTPS, vous devez activer cette option. L'utilisation de HSTS doit être considérée pour les sites Web uniquement accessible en HTTPS.
  • session.gc_maxlifetime=[le plus petit possible]. Le GC(Garbage Collector) est exécuté via un système probabiliste. Cette option ne garantie pas la suppression de vieilles sessions. Quelques modules de gestionnaire de session n'utilisent pas cette option. Raportez-vous à la documentation sur les gestionnaires de session pour plus de détails. Aussi, les développeurs ne peuvent utiliser cette option et il est recommandé de la définir à la plus petite valeur possible. Ajutez à la fois l'option session.gc_probability et l'option session.gc_divisor afin d'effacer les anciennes sessions à une fréquence appropriée. Si l'auto-identification est nécessaire, implémentez votre propre fonctionalité d'auto-identification. N'utilisez pas l'ID de la durée de vie de la session pour cela.
  • session.use_trans_sid=Off. L'utilisation du gestionnaire transparent de l'ID de session n'est pas interdite. Vous pouvez l'utiliser lorsque c'est nécessaire. Cependant, sa désactivation va améliorer la sécurité en supprimant la possibilité d'injection d'ID de session et les fuites d'ID de session.
  • session.referer_check=[votre URL d'origine] Lorsque session.use_trans_sid est actif, utilisez cette option est recommandé si c'est possible. Elle réduit les risques d'injection d'ID de session. Si votre site est http://example.com/, définissez cette option à http://example.com/. Notez que lorsque HTTPS est utilisé, le navigateur n'envoie pas l'en-tête referrer. Vi la configuration, le navigateur peut ne pas envoyer l'en-tête referrer. Toutefois, cette option n'est pas une mesure de sécurité fiable.
  • session.cache_limiter=nocache. Vous assure que le contenu HTTP n'est pas mis en cache pour l'identification de session. Autorise la mise en cache uniquement lorsque le contenu n'est pas privé. Sinon, le contenu serait exposé. "private" peut être utilisé si le contenu HTTP ne contient pas de données sensibles d'un point de vue sécurité. Notez que "private" va garder les données privées en cache pour les clients partagés. "public" peut être utilisé seulement lorsque le contenu HTTP ne contient pas du tout de données privées.
  • session.hash_function="sha256". Une fonction de hashage forte va générer un ID de session fort. Cependant, les collisions de hashage peuvent survenir avec le hash MD5 ; les développeurs doivent utiliser SHA-2 ou supérieures pour réaliser cette tâche. Les développeurs peuvent vouloir utiliser des hashes plus forts comme sha384 et sha512.

Le module de session ne garantie pas que l'information stockée dans une session n'est seulement vue que par l'utilisation qui l'a créée. Vous devez prendre des mesures complémentaires pour protéger activement la confidentialité de la session, suivant la valeur associée.

Évaluer l'importance des données transportées par vos sessions et déployez des protections supplémentaires -- cela a généralement un prix, et réduit la commodité pour l'utilisateur. Par exemple, si vous voulez protéger les utilisateurs de simples tactiques d'ingénierie sociale, vous devez activer session.use_only_cookies. Dans ce cas, les cookies doivent obligatoirement être activés côté utilisateur, sinon les sessions ne fonctionneront pas.

Il y a plusieurs façons d'exposer un ID de session existant vers une autre partie de votre site. Il lui sera alors possible d'accéder à toutes les ressources associées avec cet ID spécifique. Tout d'abord, les URLs contiennent les IDs de session. Si vous liez vers un site externe, l'URL incluent l'ID de session peut être stockée dans les logs du serveurs externes via le referrer. Deuxièmement, un attaquant plus actif peut écouter votre traffic réseau. S'il n'est pas crypté, les IDs de session vont transiter en clair sur le réseau. La solution ici est d'implémenter SSL sur votre serveur et le rendre obligatoire pour les utilisateurs. HSTS peut être utilisé pour cela.

Depuis PHP 5.5.2, session.use_strict_mode est disponible. Lorsqu'il est actif, et que le module de gestionnaire de sauvegarde le supporte, les IDs de session non initialisés seront rejectés et un nouvel ID de session sera créé. Cela protège des attaques en forcant l'utilisateur à utiliser un ID de session connu. Les attaquants peuvent passer des liens ou envoyer des mails qui contiennent un ID de session. i.e. http://example.com/page.php?PHPSESSID=123456789 Si session.use_trans_sid est actif, la victime va démarrer une session en utilisant l'ID de session fourni par l'attaquant. session.use_strict_mode limite ce type de risque.

Malgré le fait que session.use_strict_mode limite les risques, les attaquants peuvent forcer les utilisateurs à utiliser un ID de session initialisé, créé par l'attaquant. Tout ce que l'attaquant a à faire est d'initialiser un ID de session avant l'attaque et de le garder actif.

Le cookie d'ID de session peut être défini avec des attributs de domaine, de chemin, en HTTP seulement, et de sécurité. C'est la priorité définie par les navigateurs. En utilisant la priorité, l'attaquant peut définir l'ID de session qui peut être utilisé de façon permanente. L'utilisation de session.use_only_cookies ne va pas résoudre ce problème. session.use_strict_mode va limiter ce risque. Avec session.use_strict_mode=On, l'ID de session non initialisé ne sera pas accepté. Le module de session créera tojours un nouvel ID de session lorsque l'ID de session n'est pas initialisé par le module de session. Ceci peut résulter en un Dos pour la victime, mais un DoS est plus acceptable qu'un compte compromis.

session.use_strict_mode est un bon compromis, mais n'est pas suffisant pour les sessions authentifiées. Les développeurs doivent utiliser la fonction session_regenerate_id() pour l'authentification. session_regenerate_id() doit être appelée avant de définir les informations d'authentification à $_SESSION. La fonction session_regenerate_id() assure que la nouvelle session contient les informations d'authentification stockées seulement dans une nouvelle session. i.e. Les erreurs durant le processus d'authentification peut sauvegarder les drapeaux authentifiés dans l'ancienne session.

L'appel à la fonction session_regenerate_id() peut résulter en un DoS personnel comme use_strict_mode=On. Cependant, un DoS est préférable à un compte compromis. L'ID de session doit être re-généré au moins lors de l'authentification La re-génération de l'ID de session réduit le risque de son vol, ceci pouvant être périodiquement appelé. Les développeurs ne doivent pas se fier à l'expiration de l'ID de session. Les attaquants peuvent accéder à l'ID de session périodiquement pour éviter son expiration. Les développeurs doivent implémenter leurs propres fonctionalités d'expiration pour les anciennes sessions.

Notez que la fonction session_regenerate_id() ne supprime pas les anciennes sessions par défaut. Les anciennes sessions d'authentification peuvent être disponibles pour utilisation. Si le développeur veut éviter l'utilisation d'anciennes sessions d'authentification par quiconque, il doit détruire la session en définissant l'option delete_old_session à TRUE. Cependant, l'effacement immédiat des anciennes sessions a des effets de bord. La session peut disparaîte lors de connexions concurrentes à l'application Web et/ou lorsque le réseau devient instable. Au lieu de supprimer immédiatement les anciennes sessions, vous pouvez définir un délai d'expiration très court dans $_SESSION vous même. Si l'utilisateur accède à une session obsolète (session expirée), vous interdisez son accès.

session.use_only_cookies et une bonne utilisation de session_regenerate_id() peuvent engendrer un DoS personnel. Lorsque c'est le cas, vous pouvez demander à l'utilisateur de supprimer les cookies et alerter les utilisateurs qu'il y a un éventuel risque quant à la sécurité. Les attaquants peuvent définir des cookies malicieux via des applications Web vulnérables (i.e. injection JavaScript), via des plugins de navigateur vulnérables/malicieux, etc...

Les développeurs ne doivent pas utiliser un ID de session avec une grande durée de vie pour l'identification automatique car il accroit les risques de vol de session. L'auto-identification doit être implémentée par le développeurs. Utilisez une clé de hashage sécurisé à usage unique pour l'auto-identification en utilisant les cookies. Utilisez un hashage fort et plus sécurisé que SHA-2. i.e. SHA-256 ou supérieurs avec des données aléatoires provenant de /dev/urandom ou équivalent. Si l'utilisateur n'est pas authentifié, vérifiez si la clé d'auto-identification sécurisé à usage unique est valide ou non. Si la clé est valide, authentifiez l'utilisateur et définissez une nouvelle clé d'auto-identification à usage unique. La clé d'auto-identification est une clé d'authentification avec une grande durée de vie ; elle doit être protégée autant que possible. Utilisez les attributs path/httponly/secure des cookies pour la protéger. Le développeur doit implémenter la fonctionalité qui désactive l'auto-identification et qui supprime les cookies contenant les clés d'auto-identification non nécessaire pour les utilisateurs.