mirror of
https://github.com/php/doc-fr.git
synced 2026-03-24 07:02:06 +01:00
859 lines
38 KiB
XML
859 lines
38 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 55e0481a24fd4d7db21b62f1885973edbca25e60 Maintainer: yannick Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
|
|
<chapter xml:id="session.security" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Sessions et Sécurité</title>
|
|
<para>
|
|
Lien externe : <link xlink:href="&url.session-fixation;">Session fixation</link>
|
|
</para>
|
|
<para>
|
|
La gestion des sessions HTTP représente le cœur de la sécurité sur le Web.
|
|
Des mesures d'atténuation <emphasis>doivent</emphasis> être prises en compte afin d'assurer la
|
|
sécurité des sessions.
|
|
Les développeurs doivent activer/utiliser les paramètres de sécurité appropriés.
|
|
</para>
|
|
|
|
<sect1 xml:id="features.session.security.management">
|
|
<title>Gestion basique des sessions</title>
|
|
|
|
<sect2 xml:id="features.session.security.management.basic">
|
|
<title>Sécurité des sessions</title>
|
|
<para>
|
|
Le module de session ne peut pas garantir que les informations stockées
|
|
dans une session ne sont vues uniquement par l'utilisateur qui
|
|
a créé la session. Des mesures supplémentaires sont nécessaires pour
|
|
protéger la confidentialité de la session, suivant la valeur
|
|
qu'on lui associe.
|
|
</para>
|
|
|
|
<para>
|
|
L'importance des données stockées dans une session doit être évaluée
|
|
et des protections supplémentaires peuvent être déployées ;
|
|
ceci a obligatoirement un coût tel qu'être moins pratique pour
|
|
l'utilisateur. Par exemple, pour protéger les utilisateurs
|
|
d'une tactique simple, la directive <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
doit être activée. Dans ce cas, les cookies doivent être
|
|
activés obligatoirement côté client sinon les sessions ne
|
|
fonctionneront pas.
|
|
</para>
|
|
|
|
<para>
|
|
Il y a plusieurs façons de divulguer des identifiants de session à
|
|
des tierces personnes. I.E. injections Javascripts, identifiants
|
|
de session dans les URLs, reniflement de paquets, accès physique
|
|
au périphérique, etc.
|
|
Un identifiant de session divulgué permet à un tiers d'accéder
|
|
à toutes les ressources associées avec cet identifiant. Tout d'abord,
|
|
les URLs contenant les identifiants de session. S'il y a des liens
|
|
vers des sites ou des ressources externes, l'URL incluant l'identifiant
|
|
de session doit être stockée dans les logs referrer du site externe.
|
|
Si ces données ne sont pas chiffrées, les identifiants de session
|
|
vont être transmis en texte clair sur le réseau. La solution ici est
|
|
d'implémenter SSL/TLS sur le serveur et le rendre mandataire pour les
|
|
utilisateurs. HSTS devrait être utilisé pour améliorer également la
|
|
sécurité.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Même HTTPS ne peut protéger la confidentialité des données
|
|
dans tous les cas. Par exemple, les vulnérabilités CRIME et BEAST
|
|
permettent à un attaquant de lire les données. De plus, il est à noter
|
|
que certains réseaux utilisent des proxys HTTPS MITM pour
|
|
des audits. Les attaquants peuvent également mettre en place
|
|
ce genre de proxy.
|
|
</simpara>
|
|
</note>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.non-adaptive-session">
|
|
<title>Gestion des sessions non adaptatives</title>
|
|
|
|
<para>
|
|
Le gestionnaire de sessions PHP est adaptatif, par défaut.
|
|
Un gestionnaire de sessions adaptatif apporte des
|
|
risques supplémentaires.
|
|
</para>
|
|
|
|
<para>
|
|
Lorsque <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
est activé, et que le gestionnaire de sauvegarde des sessions le supporte,
|
|
un identifiant de session non initialisé est rejeté, et un nouveau est créé.
|
|
Ceci prévient une attaque qui force les utilisateurs à utiliser un
|
|
identifiant de session connu.
|
|
Un attaquant peut passer des liens ou envoyer des emails qui contiennent
|
|
l'identifiant de session.
|
|
I.e. <literal>http://example.com/page.php?PHPSESSID=123456789</literal> si
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link> est activé,
|
|
la victime commencera une session en utilisant l'identifiant de session
|
|
fourni par l'attaquant.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
permet d'annuler ce type de risque.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Les gestionnaires de sauvegarde définis par l'utilisateur peuvent
|
|
aussi supporter le mode de session strict en implémentant
|
|
la validation des identifiants de session. Tous les gestionnaires de
|
|
sauvegarde définis par l'utilisateur devraient implémenter la validation
|
|
des identifiants de session.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
Le cookie d'identifiant de session peut être défini avec les
|
|
attributs domain, path, httponly, secure et, à partir de PHP 7.3, SameSite.
|
|
Il existe une priorité définie par les navigateurs.
|
|
En utilisant les priorités, un attaquant peut définir l'identifiant de
|
|
session qui peut être utilisé en permanence. L'utilisation de la
|
|
directive <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
ne permet pas de résoudre ce problème.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
permet de mitiger ce risque. Avec la directive
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On,
|
|
l'identifiant de session non initialisé sera refusé.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Même si la directive
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
limite les risques concernant le gestionnaire adaptatif de session, un
|
|
attaquant peut forcer les utilisateurs à utiliser un identifiant de
|
|
session non initialisé qui a été créé par l'attaquant, c.-à-d. via des injections
|
|
Javascript. Ce type d'attaque peut être limité en utilisant les
|
|
recommandations de ce manuel.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
En suivant ce manuel, les développeurs devraient activer la directive
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>,
|
|
utiliser les timestamps basés sur le gestionnaire de session,
|
|
et régénérer les identifiants de session en utilisant la fonction
|
|
<function>session_regenerate_id</function> avec les procédures
|
|
recommandées. Si les développeurs suivent ces instructions, un identifiant de session
|
|
généré par un attaquant sera normalement supprimé.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
Lorsqu'un accès à une session obsolète survient, les développeurs
|
|
devraient sauvegarder toutes les données de la session active de
|
|
l'utilisateur ; ces informations seront utiles pour de futures
|
|
investigations. L'utilisateur devrait être forcé à se déconnecter
|
|
de toutes les sessions, c.-à-d. le forçant ainsi à s'identifier de
|
|
nouveau. Ceci permet de contrer les attaques utilisant des sessions
|
|
volées.
|
|
</simpara>
|
|
</note>
|
|
|
|
<warning>
|
|
<simpara>
|
|
L'accès à une session obsolète ne veut pas forcément dire qu'il s'agit d'une
|
|
attaque. Un réseau instable et/ou l'effacement immédiat de la session
|
|
active va conduire des utilisateurs légitimes à utiliser des sessions
|
|
obsolètes.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
Depuis 7.1.0, la fonction <function>session_create_id</function> a été
|
|
ajoutée. Cette fonction permet d'accéder à toutes les sessions actives
|
|
d'un utilisateur en préfixant les identifiants de session avec l'identifiant
|
|
de l'utilisateur. L'activation de la directive
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
est vital dans cette configuration. Sinon, les utilisateurs malicieux
|
|
peuvent définir des identifiants de sessions pour les autres utilisateurs.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Les utilisateurs des versions antérieures à PHP 7.1.0 <emphasis>doivent</emphasis>
|
|
utiliser <acronym>CSPRNG</acronym>, c.-à-d. <filename>/dev/urandom</filename>, ou la fonction
|
|
<function>random_bytes</function> et les fonctions de hachage
|
|
pour générer un nouvel identifiant de session. La fonction
|
|
<function>session_create_id</function> possède des mécanismes de détection
|
|
de collision, et génère un identifiant de session suivant les
|
|
configurations INI des sessions. L'utilisation de la fonction
|
|
<function>session_create_id</function> est recommandée.
|
|
</simpara>
|
|
</note>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-id-regeneration">
|
|
<title>Régénération d'un identifiant de session</title>
|
|
|
|
<para>
|
|
La directive
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
est un bon compromis mais n'est pas suffisant. Les développeurs doivent
|
|
également utiliser la fonction <function>session_regenerate_id</function>
|
|
pour la sécurité des sessions.
|
|
</para>
|
|
|
|
<para>
|
|
La régénération d'un identifiant de session réduit le risque de vol d'identifiants
|
|
de session, aussi, la fonction <function>session_regenerate_id</function>
|
|
doit être utilisée périodiquement; c.-à-d. régénérer l'identifiant de session toutes
|
|
les 15 minutes pour sécuriser le contenu sensible. Même dans le cas où
|
|
un identifiant de session est volé, à la fois le légitime utilisateur
|
|
et l'attaquant aura sa session qui va expirer. En d'autres termes, l'accès
|
|
au contenu par l'utilisateur ou l'attaquant va générer une erreur d'accès
|
|
à une session obsolète.
|
|
</para>
|
|
|
|
<para>
|
|
Les identifiants de session <emphasis>doivent</emphasis> être régénérés lorsque
|
|
les privilèges de l'utilisateur sont élevés, comme après une authentification.
|
|
La fonction <function>session_regenerate_id</function> doit être appelée
|
|
avant le stockage des informations d'authentification dans <varname>$_SESSION</varname>.
|
|
(la fonction <function>session_regenerate_id</function>
|
|
sauvegarde les données de session courantes automatiquement afin de
|
|
sauvegarder les timestamps/etc. dans la session courante.)
|
|
Il faut s'assurer que la nouvelle session contient le drapeau d'authentification.
|
|
</para>
|
|
|
|
<para>
|
|
Les développeurs <emphasis>ne doivent pas</emphasis> se baser sur
|
|
l'expiration de l'identifiant de session définie par la directive
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>.
|
|
Les attaquants peuvent accéder à l'identifiant de session de la victime
|
|
de façon périodique pour éviter son expiration, et permettre son exploitation
|
|
y compris avec des sessions authentifiées.
|
|
</para>
|
|
|
|
<para>
|
|
Au lieu de cela, les développeurs doivent implémenter un timestamp
|
|
basé sur la gestion des données de session.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Même si le gestionnaire de session peut gérer les timestamps de façon
|
|
transparente, cette fonctionnalité n'est pas implémentée. Les données
|
|
des anciennes sessions doivent être conservées tant que le récupérateur
|
|
de mémoire ne soit passé. Simultanément, les développeurs doivent s'assurer
|
|
eux-mêmes que les données de session obsolètes soient effectivement effacées.
|
|
Cependant, les développeurs ne doivent pas supprimer les données
|
|
de session active trop rapidement. c.-à-d. <code>session_regenerate_id(true);</code>
|
|
et <function>session_destroy</function> ne doivent jamais être appelés
|
|
en même temps pour une session active. Ça peut paraître contradictoire,
|
|
mais c'est une exigence du mandataire.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
<function>session_regenerate_id</function> <emphasis>n'effacera pas</emphasis>
|
|
les anciennes sessions par défaut. Les sessions authentifiées obsolètes
|
|
peuvent être présentées pour être utilisées. Les développeurs doivent s'assurer
|
|
que les anciennes sessions ne soient pas utilisées par tout le monde.
|
|
Ils doivent interdire l'accès aux données de session obsolète
|
|
en utilisant eux-mêmes des timestamps.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
La suppression soudaine d'une session active produit des effets de bords
|
|
indésirables. Les sessions peuvent disparaître lorsqu'il y a des connexions
|
|
concurrentes sur l'application web et/ou lorsque le réseau est instable.
|
|
</simpara>
|
|
<simpara>
|
|
Les accès potentiellement malicieux sont indétectables avec la suppression
|
|
soudaine d'une session.
|
|
</simpara>
|
|
<simpara>
|
|
Au lieu de supprimer les sessions obsolètes immédiatement, les développeurs
|
|
doivent définir un court temps d'expiration (timestamp) dans
|
|
<varname>$_SESSION</varname>, et interdire l'accès aux données de session.
|
|
</simpara>
|
|
<simpara>
|
|
Les développeurs ne doivent pas interdire l'accès aux données des
|
|
anciennes sessions immédiatement après l'exécution de la fonction
|
|
<function>session_regenerate_id</function>. L'accès doit être interdit
|
|
à un stade ultérieur ; c.-à-d. quelques secondes après pour les réseaux
|
|
stables, comme un réseau filaire et quelques minutes après pour les réseaux
|
|
instables comme des téléphones mobiles ou des réseaux Wi-Fi.
|
|
</simpara>
|
|
<simpara>
|
|
Si un utilisateur accède à une session obsolète (session ayant expirée), l'accès
|
|
à cette session doit être refusé. Il est également recommandé de supprimer le
|
|
statut d'authentification de toutes les sessions utilisateurs, car cela
|
|
peut représenter un axe d'attaque.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
L'utilisation de la directive <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link> et de la fonction
|
|
<function>session_regenerate_id</function> peuvent causer des DoS personnel
|
|
avec des cookies non-supprimés définis par les attaquants. Dans ce cas,
|
|
les développeurs peuvent inviter les utilisateurs à supprimer les cookies
|
|
et les avertir qu'ils peuvent rencontrer un problème de sécurité.
|
|
Les attaquants peuvent définir des cookies malicieux via une application
|
|
web vulnérable, un plugin de navigateur exposé ou vicié, un périphérique
|
|
physique compromis, etc.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Il ne faut pas se méprendre sur le risque DoS. <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
|
est obligatoire pour la sécurité des identifiants de session !
|
|
Tous les sites sont encouragés à activer la directive
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>.
|
|
</simpara>
|
|
<simpara>
|
|
DoS peut uniquement survenir lorsque le compte subit une attaque. Une injection
|
|
Javascript dans une application représente la plupart des axes d'attaque.
|
|
</simpara>
|
|
</warning>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-data-deletion">
|
|
<title>Suppression des données de session</title>
|
|
|
|
<para>
|
|
Les données de sessions obsolètes doivent être inaccessibles
|
|
et doivent être supprimées. Le module courant de session
|
|
ne prend pas en charge cet aspect.
|
|
</para>
|
|
|
|
<para>
|
|
Les données de sessions obsolètes doivent être supprimées aussi vite
|
|
que possible. Cependant, les sessions actives ne doivent pas être
|
|
supprimées instantanément. Pour satisfaire ces recommandations, les développeurs
|
|
eux-mêmes doivent implémenter un gestionnaire des données de session basé sur
|
|
un timestamp.
|
|
</para>
|
|
|
|
<para>
|
|
Définir et gérer l'expiration du timestamp dans la variable
|
|
globale $_SESSION. Interdire l'accès aux données de sessions
|
|
périmées. Lorsqu'un accès à des données de session obsolète est détecté,
|
|
il convient de supprimer toutes les statuts authentifiés des sessions
|
|
utilisateurs et forcer les utilisateurs à s'authentifier de nouveau.
|
|
L'accès à des données de sessions obsolètes peut représenter une attaque.
|
|
Pour arriver à cette fin, les développeurs doivent suivre toutes les sessions
|
|
actives de tous les utilisateurs.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
L'accès à une session obsolète peut également survenir à cause d'un réseau instable
|
|
et/ou d'un accès concurrent à un site web, c.-à-d. le serveur tente de définir un
|
|
nouvel identifiant de session via un cookie, mais le paquet Set-Cookie n'a jamais
|
|
atteint le client en raison d'une perte de connexion. Une connexion peut
|
|
créer un nouvel identifiant de session via la fonction <function>session_regenerate_id</function>,
|
|
mais une autre connexion concurrente peut ne pas avoir encore reçu
|
|
l'identifiant de session. Toutefois, les développeurs doivent interdire l'accès
|
|
à une session obsolète à un moment plus éloigné. c.-à-d. la gestion des sessions
|
|
basés sur le timestamp est obligatoire.
|
|
</simpara>
|
|
</note>
|
|
|
|
<para>
|
|
En résumé, les données de sessions ne doivent pas être détruites avec la fonction
|
|
<function>session_regenerate_id</function>, ni avec la fonction <function>session_destroy</function>,
|
|
mais les timestamps doivent être utilisés pour contrôler l'accès aux données de
|
|
session. Laissez la fonction <function>session_gc</function> supprimer les données obsolètes
|
|
depuis le stockage des données de sessions.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-locking">
|
|
<title>Session et Verrouillage</title>
|
|
|
|
<para>
|
|
Les données de session sont verrouillées par défaut pour éviter les
|
|
accès concurrent. Le verrouillage est obligatoire pour conserver une
|
|
consistance des données de session au travers les requêtes.
|
|
</para>
|
|
|
|
<para>
|
|
Cependant, le verrouillage de session peut être utilisé par les attaquants
|
|
pour réaliser des attaques DoS. Pour minimiser le risque d'une attaque DoS
|
|
par verrouillage de session, il convient de minimiser les verrous.
|
|
Utiliser des données en lecture seule lorsque les données de session
|
|
n'ont pas besoin d'être mises à jour. Utiliser l'option 'read_and_close'
|
|
avec la fonction <function>session_start</function>.
|
|
<code>session_start(['read_and_close'=>1]);</code> va clôre
|
|
la session aussi vite que possible après la mise à jour de la variable
|
|
globale $_SESSION en utilisant la fonction <function>session_commit</function>.
|
|
</para>
|
|
|
|
<para>
|
|
Le module de session courant <emphasis>ne détecte pas</emphasis>
|
|
toutes les modifications de la variable $_SESSION lorsque
|
|
la session est inactive. Il en va de la responsabilité du développeur
|
|
de ne pas modifier la variable $_SESSION lorsque la session est inactive.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.active-sessions">
|
|
<title>Sessions actives</title>
|
|
|
|
<para>
|
|
Les développeurs doivent conserver une trace de toutes les sessions
|
|
actives de chaque utilisateur, et leur notifier le nombre de sessions
|
|
actives, depuis quelle adresse IP, depuis combien de temps, etc.
|
|
PHP ne conserve pas de traces de ces informations. Les développeurs
|
|
sont supposés le faire eux-mêmes.
|
|
</para>
|
|
|
|
<para>
|
|
Il existe différentes façons de faire cela. Une implémentation possible
|
|
est de définir une base de données qui conserve une trace des données
|
|
nécessaires, et y stocker toutes les informations pertinentes.
|
|
Depuis que les données de session sont GCed, les développeurs doivent
|
|
faire attention aux données GCed pour maintenir la base de données
|
|
des sessions actives consistante.
|
|
</para>
|
|
|
|
<para>
|
|
Une des implémentations simple est "l'identifiant utilisateur préfixant
|
|
l'identifiant de session" et stocker les informations nécessaires dans
|
|
la variable $_SESSION. La plupart des bases de données sont relativement
|
|
performantes pour sélectionner un préfixe sous la forme d'une &string;.
|
|
Les développeurs DOIVENT utiliser la fonction <function>session_regenerate_id</function>
|
|
ainsi que la fonction <function>session_create_id</function> pour cela.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
N'utiliser jamais de données confidentielles comme préfixe.
|
|
Si l'identifiant utilisateur est confidentiel, il est recommandé d'utiliser
|
|
la fonction <function>hash_hmac</function>.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<warning>
|
|
<simpara>
|
|
L'activation de la directive
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
est obligatoire pour ce type de configuration. Il faut s'assurer qu'il
|
|
est activé. Sinon, la base de données des sessions actives
|
|
peut être compromise.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
Le gestionnaire de session basé sur un timestamp est obligatoire
|
|
pour détecter l'accès à des sessions obsolètes. Lorsque l'accès à une
|
|
session obsolète est détecté, le drapeau d'authentification doit
|
|
être supprimé de toutes les sessions actives de l'utilisateur.
|
|
Ceci permet d'éviter aux attaquants de continuer à exploiter les sessions
|
|
volées.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-and-autologin">
|
|
<title>Session et l'auto-identification</title>
|
|
|
|
<para>
|
|
Les développeurs ne doivent pas utiliser d'identifiants de session avec une
|
|
grande durée de vie pour l'auto-identification, car cela accroit le risque
|
|
d'utiliser des sessions volées. Une fonctionnalité d'auto-identification
|
|
doit être implémentée par le développeur.
|
|
</para>
|
|
|
|
<para>
|
|
Utiliser une clé de hachage sécurisé à usage unique comme clé
|
|
d'auto-identification en utilisant la fonction
|
|
<function>setcookie</function>. Utiliser un hachage sécurisé
|
|
plus fort que SHA-2. c.-à-d. SHA-256 ou supérieur avec des données
|
|
aléatoires depuis la fonction <function>random_bytes</function>
|
|
ou via <filename>/dev/urandom</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
Si l'utilisateur est non authentifié, vérifiez si la clé d'auto-identification
|
|
à usage unique est valide ou non. Dans ce cas où elle est valide, authentifiez
|
|
l'utilisateur et définissez une nouvelle clé de hachage sécurisée à usage unique.
|
|
Une clé d'auto-identification ne doit être utilisée qu'une seule fois, c.-à-d. n'utiliser
|
|
jamais une clé d'auto-identification, et régénérez-la toujours.
|
|
</para>
|
|
|
|
<para>
|
|
Une clé d'auto-identification est une clé d'authentification avec une
|
|
longue durée, elle doit être protégée autant que possible.
|
|
Utiliser les attributs de cookie path/httponly/secure/SameSite pour la sécurité.
|
|
c.-à-d. ne transmettez jamais la clé d'auto-identification tant que cela
|
|
n'est pas nécessaire.
|
|
</para>
|
|
|
|
<para>
|
|
Les développeurs doivent implémenter les fonctionnalités qui
|
|
désactivent l'auto-identification, et suppriment les cookies
|
|
contenant les clés d'auto-identification non nécessaires.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.csrf">
|
|
<title>Attaques CSRF (Cross-Site Request Forgeries)</title>
|
|
|
|
<para>
|
|
Les sessions et les authentifications ne protègent pas contre les
|
|
attaques CSRF. Les développeurs doivent implémenter des protections
|
|
CSRF eux-mêmes.
|
|
</para>
|
|
|
|
<para>
|
|
La fonction <function>output_add_rewrite_var</function> peut être utilisée pour
|
|
la protection CSRF. Se référer aux pages du manuel pour plus de détails.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
PHP, avant sa version 7.2.0, utilise le même buffer de sortie et les
|
|
mêmes configurations INI que la configuration trans-sid. Toutefois, l'utilisation
|
|
de la fonction <function>output_add_rewrite_var</function> avec les versions
|
|
de PHP antérieures à 7.2.0 n'est pas conseillée.
|
|
</simpara>
|
|
</note>
|
|
|
|
<para>
|
|
La plupart des frameworks d'applications web supportent
|
|
la protection CSRF. Se référer au manuel du
|
|
framework d'application web pour plus de détails.
|
|
</para>
|
|
|
|
<para>
|
|
À partir de PHP 7.3, l'attribut SameSite du cookie de session peut être défini.
|
|
Ceci est une mesure supplémentaire qui peut minimiser
|
|
les vulnérabilités CSRF.
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="session.security.ini">
|
|
<title>Sécurisation des configurations INI de session</title>
|
|
|
|
<para>
|
|
En sécurisant les configurations INI de sessions, les développeurs
|
|
peuvent éprouver la sécurité des sessions. Beaucoup de configurations
|
|
INI n'ont pas de configuration recommandée. Les développeurs sont
|
|
responsables de la bonne configuration des sessions.
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-lifetime">session.cookie_lifetime</link>=0
|
|
</para>
|
|
<para>
|
|
La valeur <literal>0</literal> a une signification importante.
|
|
Elle informe les navigateurs de ne pas stocker le cookie dans un
|
|
espace de stockage permanent. Aussi, lorsque le navigateur se ferme,
|
|
le cookie d'identification de session est supprimé immédiatement.
|
|
Si les développeurs définissent une valeur différente de 0, cela permet
|
|
aux autres utilisateurs d'utiliser l'identifiant de session. La
|
|
plupart des applications devraient utiliser "<literal>0</literal>" comme
|
|
valeur.
|
|
</para>
|
|
<para>
|
|
Si une fonctionnalité d'auto-identification est désirée, les développeurs
|
|
doivent implémenter leur propre système d'auto-identification sécurité.
|
|
N'utiliser pas des identifiants de session à longue durée pour cela.
|
|
Pour plus d'informations, se rapporter à la bonne section
|
|
de cette documentation.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-cookies">session.use_cookies</link>=On
|
|
</para>
|
|
<para>
|
|
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=On
|
|
</para>
|
|
<para>
|
|
Bien que les cookies HTTP souffrent de soucis techniques, ils
|
|
restent la façon préférée de gérer les identifiants de sessions.
|
|
N'utiliser que les cookies pour la gestion des identifiants de sessions
|
|
lorsque cela est possible. La plupart des applications doivent utiliser
|
|
un cookie pour l'identifiant de session.
|
|
</para>
|
|
<para>
|
|
Si <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=Off,
|
|
le module de session utilisera les valeurs de l'identifiant
|
|
de sessions définies par les variables GET ou POST fournies,
|
|
et le cookie de l'identifiant de session ne sera pas initialisé.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
|
</para>
|
|
<para>
|
|
Bien que l'activation de <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
soit obligatoire pour la sécurité des sessions, cette directive est
|
|
désactivée par défaut.
|
|
</para>
|
|
<para>
|
|
Ce mode évite que le module de session utilise un identifiant de session
|
|
non initialisé. Dit différemment, le module de session ne va accepter
|
|
que les identifiants de sessions valides générés par le module de session.
|
|
Il va rejeter tous les identifiants de session fournis par les utilisateurs.
|
|
</para>
|
|
<para>
|
|
En raison de la spécification des cookies, les attaquants sont capables
|
|
de placer des cookies contenant les identifiants de sessions en configurant
|
|
localement une base de données de cookie ou par injections Javascript.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> peut éviter qu'un attaquant
|
|
n'initialise un identifiant de session.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Les attaquants peuvent initialiser un identifiant de session avec leur
|
|
propre périphérique, et peuvent définir l'identifiant de session
|
|
de leur victime. Ils doivent alors conserver l'identifiant de session
|
|
actif pour pouvoir en abuser.
|
|
Les attaquants doivent passer par bien d'autres étapes pour réussir leur attaque
|
|
dans ce scénario. Aussi, l'utilisation de la directive
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> permet de limiter les risques.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-httponly">session.cookie_httponly</link>=On
|
|
</para>
|
|
<para>
|
|
Permet de refuser l'accès à un cookie de session depuis javascript.
|
|
Cette configuration évite qu'un cookie ne soit corrompu par une
|
|
injection Javascript.
|
|
</para>
|
|
<para>
|
|
Il est possible d'utiliser un identifiant de session comme jeton CSRF, mais
|
|
ce n'est pas recommandé. Par exemple, des sources HTML peuvent être
|
|
sauvegardées et envoyées à d'autres utilisateurs.
|
|
Les développeurs ne doivent pas écrire les identifiants de session dans les
|
|
pages web pour des raisons de sécurité. Toutes les applications web doivent
|
|
utiliser l'attribut httponly pour le cookie contenant l'identifiant de session.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Le jeton CSRF doit être renouvelé périodiquement, tout comme l'identifiant
|
|
de session.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-secure">session.cookie_secure</link>=On
|
|
</para>
|
|
<para>
|
|
Permet d'accéder au cookie d'identifiant de session uniquement lorsque
|
|
le protocole est HTTPS. Si un site web n'est accessible que par HTTPS,
|
|
cette directive doit être activée.
|
|
</para>
|
|
<para>
|
|
HSTS doit être utilisé pour les sites web accessibles que par HTTPS.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Lax" ou
|
|
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Strict"
|
|
</para>
|
|
<para>
|
|
À partir de PHP 7.3, l'attribut <literal>"SameSite"</literal> peut être défini
|
|
pour le cookie d'identifiant de session. Cet attribut est une façon de
|
|
mitiger les attaques CSRF (Cross Site Request Forgery).
|
|
</para>
|
|
<para>
|
|
La différence entre Lax et Strict est l'accessibilité du cookie dans les requêtes
|
|
originaires d'autres domaines employant la méthode HTTP GET.
|
|
Les cookies utilisant Lax seront accessibles via une requête GET originaire
|
|
d'un autre domaine, alors que les cookies utilisant Strict ne le seront pas.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>=[choisissez le plus petit possible]
|
|
</para>
|
|
<para>
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link> est une configuration pour supprimer
|
|
l'identifiant de session obsolète. Le fait de se reposer
|
|
entièrement sur cette configuration <emphasis>n'est pas</emphasis> recommandé.
|
|
Les développeurs doivent gérer la durée de vie des sessions avec un timestamp
|
|
par eux-mêmes.
|
|
</para>
|
|
<para>
|
|
Le GC des sessions (garbage collection) est mieux réalisé en utilisant
|
|
la fonction <function>session_gc</function>.
|
|
La fonction <function>session_gc</function> doit être exécutée par un gestionnaire
|
|
de tâches ; c.-à-d. un cron sur les systèmes Unix.
|
|
</para>
|
|
<para>
|
|
GC est exécuté par probabilité, par défaut. Cette configuration
|
|
<emphasis>ne garantit pas</emphasis> que les anciennes sessions soient
|
|
supprimées. Bien que les développeurs ne doivent pas s'appuyer sur ce paramètre,
|
|
il est recommandé tout de même de le définir à une valeur la plus petite possible.
|
|
Il convient d'ajuster les directives <link
|
|
linkend="ini.session.gc-probability">session.gc_probability</link>
|
|
et <link
|
|
linkend="ini.session.gc-divisor">session.gc_divisor</link> de sorte à ce que
|
|
les sessions obsolètes soient supprimées à fréquence appropriée.
|
|
Si la fonctionnalité d'auto-identification est nécessaire, les développeurs
|
|
doivent implémenter leur propre fonctionnalité d'auto-identification sécurisée ;
|
|
voir ci-dessous pour plus d'informations. N'utiliser jamais l'identifiant
|
|
de session de longue durée pour réaliser ce genre de fonctionnalité.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Quelques modules de gestion de sauvegarde des sessions n'utilisent pas cette
|
|
fonctionnalité basée sur l'expiration et sur la probabilité ; c.-à-d.
|
|
memcached, memcache. Se référer à la documentation de ces gestionnaires
|
|
de sauvegarde des sessions pour plus de détails.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>=Off
|
|
</para>
|
|
<para>
|
|
L'utilisation d'un gestionnaire d'identifiants de sessions transparent
|
|
n'est pas interdit. Les développeurs doivent l'employer lorsque nécessaire.
|
|
Pourtant, la désactivation de la gestion des identifiants de session de
|
|
façon transparente permet de sécuriser un peu plus les identifiants de session
|
|
en éliminant la possibilité d'une injection d'identifiant de sessions ou
|
|
de fuite de cet identifiant.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
L'identifiant de session peut fuiter depuis des URLs sauvegardées,
|
|
des URLs dans des emails, d'une source HTML sauvegardée, etc.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.trans-sid-tags">session.trans_sid_tags</link>=[drapeaux limités]
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 >=) Les développeurs ne doivent pas réécrire de drapeaux HTML
|
|
non nécessaires. La valeur par défaut doit être suffisante pour la
|
|
plupart des utilisations. Pour les versions de PHP plus anciennes,
|
|
utiliser plutôt
|
|
<link linkend="ini.url-rewriter.tags">url_rewriter.tags</link>.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.trans-sid-hosts">session.trans_sid_hosts</link>=[hôtes limités]
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 >=) Ce paramètre définit une liste blanche des hôtes qui sont
|
|
autorisés à réécrire les identifiants de session transparents. Ne jamais
|
|
ajouter d'hôte qui ne sont pas de confiance !
|
|
Le module de session autorise uniquement <literal>$_SERVER['HTTP_HOST']</literal>
|
|
lorsque ce paramètre est vide.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.referer-check">session.referer_check</link>=[URL d'origine]
|
|
</para>
|
|
<para>
|
|
Lorsque le paramètre <link
|
|
linkend="ini.session.use-trans-sid">session.use_trans_sid</link>
|
|
est actif.
|
|
Ce paramètre réduit les risques d'injection d'identifiant de session.
|
|
Si un site web est <literal>http://example.com/</literal>,
|
|
définissez comme valeur à ce paramètre <literal>http://example.com/</literal>.
|
|
Il est à noter que les navigateurs HTTPS n'envoient pas l'en-tête referrer.
|
|
Les navigateurs peuvent ne pas envoyer l'en-tête referrer de part
|
|
leur propre configuration. Aussi, ce paramètre ne peut pas être
|
|
considéré comme une mesure fiable de sécurité.
|
|
Malgré tout, son utilisation est recommandée.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cache-limiter">session.cache_limiter</link>=nocache
|
|
</para>
|
|
<para>
|
|
S'assure que le contenu HTTP n'est pas mis en cache pour les sessions
|
|
authentifiées. Permet la mise en cache que pour les contenus
|
|
qui ne sont pas privés. Sinon, le contenu sera exposé.
|
|
La valeur <literal>"private"</literal> doit être employée si le contenu HTTP n'inclut pas
|
|
des données sensibles d'un point de vue sécurité. Il est à noter que <literal>"private"</literal>
|
|
peut transmettre des données privées mises en cache pour les clients
|
|
partagés. <literal>"public"</literal> doit être uniquement utilisé lorsque le contenu HTML
|
|
ne contient aucune donnée privée.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.hash-function">session.hash_function</link>="sha256"
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 <) Une fonction de hachage forte va générer un identifiant
|
|
de session fort. Bien qu'une collision de hachage soit peu probable avec des
|
|
algorithmes de hachage MD5, les développeurs doivent utiliser SHA-2 ou un
|
|
algorithme de hachage plus fort comme sha384 et sha512.
|
|
Les développeurs doivent s'assurer d'une longueur suffisante de
|
|
l'<link linkend="ini.session.entropy-length">entropie</link> pour la
|
|
fonction de hachage utilisée.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.save-path">session.save_path</link>=[dossier non lisible par tout le monde]
|
|
</para>
|
|
<para>
|
|
Si ce paramètre est défini à un dossier accessible en lecture par tout le monde,
|
|
comme <filename>/tmp</filename> (par défaut), les autres utilisateurs du serveur
|
|
seront capables de récupérer les sessions en listant les fichiers présents
|
|
dans ce répertoire.
|
|
</para>
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
</sect1>
|
|
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|
|
|