Situation actuelle : PHP2Shell. Deux failles PHP critiques (CVSS 9.2) permettent d'exécuter du code malveillant sans authentification. Correctifs disponibles depuis le 21 octobre 2026.Ce qu'il faut faire maintenant →

Sessions et cookies en PHP

Les sessions transforment le HTTP sans état en une connexion qui tient sur plusieurs pages. Voici comment PHP le résout en interne, quelles valeurs par défaut s'appliquent et le lien entre session.upload_progress et PHP2Shell.

État 5 min de lectureSavoir PHP

En bref : le HTTP ne retient rien entre deux requêtes. Une session PHP résout ce problème : PHP attribue un ID de session aléatoire, l'envoie au navigateur sous forme de cookie et stocke les données associées sur le serveur, par défaut sous forme de fichier. À chaque requête suivante, session_start() relit les données à partir de l'ID. La fonction session.upload_progress fait aussi partie de la session PHP ; à cause de PHP2Shell, php.net recommande de la désactiver temporairement côté serveur.

Pourquoi les applications web ont besoin de sessions

Chaque requête adressée à un serveur web est autonome. Sans mécanisme supplémentaire, une boutique ne saurait plus, au clic sur « Panier », qui vient d'y mettre quelque chose, et un espace d'administration devrait redemander le mot de passe à chaque clic. Les sessions relient les requêtes individuelles en une session.

Pour les décideurs, cela signifie : après la connexion, l'ID de session vaut autant que l'identifiant et le mot de passe réunis. Pour les administrateurs, cela signifie : l'endroit et la manière dont les données de session sont stockées est une question de sécurité, surtout sur les serveurs hébergeant plusieurs sites.

Ce qui se passe avec session_start()

Le déroulement est le même à chaque requête et peut se décrire en cinq étapes :

  1. Le navigateur envoie le cookie portant le nom de session, par défaut PHPSESSID.
  2. session_start() lit l'ID et le transmet au gestionnaire de stockage, par défaut files.
  3. Le gestionnaire charge les données stockées, PHP les reconvertit avec le serialize_handler et remplit $_SESSION.
  4. Le script lit et modifie $_SESSION comme un tableau ordinaire.
  5. À la fin de la requête, PHP réécrit les données. Avec session.lazy_write (par défaut : activé), seulement si elles ont changé.
<?php
session_start();

$_SESSION['besuche'] = ($_SESSION['besuche'] ?? 0) + 1;
echo 'Seitenaufrufe in dieser Sitzung: ', (int) $_SESSION['besuche'];

S'il n'existe pas encore de session, PHP génère un nouvel ID et définit le cookie. Si session.use_strict_mode est actif, PHP refuse les ID inconnus imposés par le navigateur et en génère un nouveau. Le manuel PHP qualifie ce réglage d'impératif pour la sécurité de base.

Valeurs par défaut à connaître

Les valeurs suivantes s'appliquent, selon le manuel PHP, lorsque rien d'autre n'est configuré. De nombreuses distributions et hébergeurs définissent leurs propres valeurs ; ce qui compte est donc toujours la configuration effectivement en vigueur.

Réglage Par défaut Signification
session.save_handler files emplacement des données, Redis ou base de données aussi possibles
session.name PHPSESSID nom du cookie
session.serialize_handler php format des données stockées
session.use_strict_mode 0 les ID inconnus sont acceptés
session.use_only_cookies 1 pas d'ID de session dans l'adresse
session.cookie_httponly 0 JavaScript peut lire le cookie
session.cookie_secure 0 cookie aussi via HTTP non chiffré
session.cookie_samesite vide pas d'attribut SameSite
session.gc_maxlifetime 1440 secondes avant le nettoyage possible
session.gc_probability / gc_divisor 1 / 100 nettoyage environ tous les cent démarrages
session.upload_progress.enabled 1 la progression du téléversement est écrite dans la session

Les valeurs de cookie_httponly, cookie_secure et use_strict_mode ne sont donc pas conçues pour la sécurité en sortie d'usine. La manière de les définir correctement est décrite dans le guide Sécuriser les sessions en PHP. Les réglages session.sid_length et session.sid_bits_per_character sont marqués comme obsolètes depuis PHP 8.4.0.

Définir directement des cookies

Outre le cookie de session, une application peut définir ses propres cookies. Depuis PHP 7.3.0, setcookie() accepte pour cela un tableau d'options, y compris samesite. Depuis PHP 8.5.0, l'option partitioned s'y ajoute.

<?php
setcookie('sprache', 'de', [
    'expires'  => time() + 60 * 60 * 24 * 30,
    'path'     => '/',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

Selon le manuel, avec samesite égal à None, secure doit aussi être défini, sinon le navigateur bloque le cookie. Les cookies sont des données du navigateur : leur contenu revient à la requête suivante via $_COOKIE et doit être vérifié comme toute autre saisie. Plus de détails sur la page Superglobales.

session.upload_progress : affichage de la progression des téléversements

PHP peut écrire la progression dans la session pendant un téléversement de fichier. Pour cela, le formulaire envoie un champ caché portant le nom défini dans session.upload_progress.name, par défaut PHP_SESSION_UPLOAD_PROGRESS. PHP place alors les données dans $_SESSION sous une clé préfixée par upload_progress_, avec des indications comme l'heure de début, la taille totale et les octets déjà traités.

Point important pour la compréhension : selon le manuel, PHP écrit ces informations dans la session avant que le moindre script ne soit exécuté. La fonction agit donc pendant le traitement de la requête, avant même le code de l'application. Ses réglages sont de type INI_PERDIR et ne peuvent pas être modifiés à l'exécution.

Sessions et PHP2Shell : la mesure transitoire

Parmi les mesures transitoires contre les failles PHP2Shell, php.net cite la définition de session.upload_progress.enabled=0 dans le php.ini, dans le pool FPM ou dans la configuration du serveur, puis le redémarrage de tous les workers, expressément pas via ini_set() ni .user.ini. Le 23/10/2026 s'est ajouté l'avis sur CVE-2026-115560, avec le même remède jusqu'à la prochaine version corrective régulière.

; pool FPM du site web, puis redémarrer tous les workers
php_admin_flag[session.upload_progress.enabled] = off

Selon des rapports spécialisés, ce réglage seul ne comble pas les deux failles. La mise à jour vers PHP 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 reste obligatoire. L'article Désactiver session.upload_progress décrit si votre application utilise du tout la progression des téléversements et comment définir durablement le réglage.

Comment PHP SOS aide-t-il concrètement ?

  • Nous relevons les réglages de session effectivement en vigueur pour chaque site web, et pas seulement les valeurs de la ligne de commande.
  • Nous appliquons les mesures transitoires PHP2Shell pool par pool, redémarrons tous les workers et vérifions le résultat.
  • Nous séparons les emplacements de session et les utilisateurs de pool entre les sites web dans le cadre du durcissement de serveur.
  • Après un incident, nous invalidons toutes les sessions existantes, afin que les ID de session volés ne valent plus rien.

Questions fréquentes

Quelle est la différence entre un cookie et une session ?

Un cookie est un petit jeu de données que le navigateur stocke et renvoie à chaque requête. Une session stocke les données proprement dites sur le serveur ; le cookie ne contient qu'un identifiant aléatoire, l'ID de session.

Combien de temps vit une session PHP ?

Le cookie de session est valable par défaut jusqu'à la fermeture du navigateur. Les données sur le serveur peuvent être nettoyées après session.gc_maxlifetime, par défaut 1440 secondes sans accès. Le moment où cela se produit réellement dépend de la logique de nettoyage du système.

Que fait session.upload_progress ?

Cette fonction écrit pendant un téléversement de fichier la progression dans la session, afin qu'une seconde requête puisse l'afficher. Elle est active par défaut. En raison de PHP2Shell, php.net recommande de la désactiver temporairement côté serveur.

Suffit-il de désactiver session.upload_progress avec ini_set() ?

Non. Selon le manuel, le réglage ne peut de toute façon pas être modifié à l'exécution, et php.net cite expressément le php.ini, le pool FPM ou la configuration du serveur comme bons emplacements, et non ini_set() ou .user.ini. Redémarrez ensuite tous les workers.

Sources

Contact immédiat

Chaque heure compte. Écrivez-nous maintenant.

Décrivez brièvement votre système, votre version de PHP et ce que vous avez observé. Nous vous répondons, faisons le point et travaillons à distance jusqu'à la clôture et la documentation de l'incident.

Aide immédiate