En bref : les superglobales sont des tableaux prédéfinis que PHP remplit automatiquement à chaque requête et qui sont disponibles partout dans le code. $_GET contient les paramètres de l'adresse, $_POST les données de formulaire, $_FILES les fichiers téléversés, $_COOKIE les cookies et $_SERVER des informations sur la requête et le serveur. PHP crée ces tableaux avant que le code de votre application ne démarre. C'est pourquoi des failles dans ce traitement précis, comme avec PHP2Shell, ne peuvent pas être interceptées par des vérifications dans l'application.
Que sont les superglobales ?
En PHP, une variable n'est normalement valable que dans la fonction où elle a été créée. Les superglobales sont l'exception : elles sont disponibles dans chaque portée, sans qu'il faille les récupérer avec global. Le manuel PHP en cite neuf.
Pour les non-techniciens, on peut le décrire ainsi : les superglobales sont la boîte aux lettres de l'application. Tout ce qu'un visiteur envoie y atterrit avant que l'application ne le lise. Et tout ce qui se trouve dans la boîte aux lettres provient potentiellement d'un inconnu.
Les superglobales en un coup d'œil
| Superglobale | Contenu | Origine |
|---|---|---|
$_GET |
paramètres de l'adresse (query string) | client |
$_POST |
champs de formulaire d'une requête POST | client |
$_FILES |
informations sur les fichiers téléversés | client, préparées par PHP |
$_COOKIE |
cookies envoyés par le navigateur | client |
$_REQUEST |
mélange de GET, POST et éventuellement des cookies | client |
$_SERVER |
en-têtes de requête, méthode, chemins, informations du serveur | serveur web et client mélangés |
$_ENV |
variables d'environnement | serveur |
$_SESSION |
données de la session en cours | stockage serveur |
$GLOBALS |
toutes les variables globales | script |
$_SERVER est particulièrement sournoise. Selon le manuel, PHP crée pour chaque en-tête de requête une entrée commençant par HTTP_, par exemple HTTP_USER_AGENT. Ces valeurs sont définies par le client lui-même. SERVER_NAME peut, selon le manuel, contenir le nom d'hôte fourni par le client et n'est pas fiable pour des décisions de sécurité.
Comment PHP remplit les superglobales
Avant que le premier caractère de votre script ne soit exécuté, PHP a déjà travaillé. Il lit l'adresse, les en-têtes et le contenu de la requête, les décompose et place les résultats dans les tableaux. Plusieurs réglages pilotent cette étape :
variables_order(par défautEGPCS) détermine quelles superglobales sont créées : Environment, GET, POST, Cookie, Server.request_order(par défaut vide) détermine à partir de quoi$_REQUESTest constitué. S'il est vide,variables_orders'applique. Selon le manuel, les fichiers php.ini fournis omettent les cookies pour des raisons de sécurité.max_input_vars(par défaut1000) etmax_input_nesting_level(par défaut64) limitent le nombre et l'imbrication des variables d'entrée.post_max_size(par défaut8M) limite le contenu de la requête. Si une requête est plus grande,$_POSTet$_FILESrestent vides.enable_post_data_reading(par défaut activé) détermine si PHP analyse automatiquement le contenu des requêtes POST.
Si enable_post_data_reading est désactivé, l'application lit elle-même le contenu brut via php://input. Depuis PHP 8.4.0, il existe en outre request_parse_body(), qui analyse les données de formulaire et de téléversement aussi pour d'autres méthodes que POST et permet des limites propres. Le déroulement détaillé de la partie téléversement est expliqué sur la page Comment PHP traite les téléversements de fichiers.
Traiter les données de requête en sécurité
Le principe est simple : toute valeur de $_GET, $_POST, $_COOKIE, $_FILES et des entrées HTTP_ de $_SERVER est une entrée étrangère. Elle est vérifiée à la réception et échappée de manière adaptée à la sortie.
<?php
declare(strict_types=1);
// Entier attendu : vérifier plutôt que convertir à l'aveugle
$seite = filter_var($_GET['seite'] ?? '1', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 500],
]);
if ($seite === false) {
http_response_code(400);
exit('Ungültige Seitenzahl');
}
// N'autoriser que les valeurs permises
$sortierung = in_array($_GET['sort'] ?? '', ['name', 'datum'], true)
? $_GET['sort']
: 'datum';
// Toujours échapper la sortie
echo htmlspecialchars($_POST['kommentar'] ?? '', ENT_QUOTES, 'UTF-8');
Un piège fréquent concerne les indications sur l'origine d'une requête. Si un reverse proxy, un répartiteur de charge ou un CDN se trouve devant le serveur web, $_SERVER['REMOTE_ADDR'] contient l'adresse de cet intermédiaire, non celle du visiteur. L'adresse réelle figure alors dans un en-tête comme X-Forwarded-For, que chaque client peut toutefois définir lui-même. L'application ne doit exploiter de tels en-têtes que si la requête provient manifestement d'un proxy connu et sous votre contrôle. Sinon, les blocages par adresse IP ou les journaux sont facilement trompés. Il en va de même pour HTTPS : si le chiffrement prend fin au proxy, l'application doit savoir expressément que la connexion d'origine était chiffrée.
D'autres modèles de validation et de filtrage figurent dans l'article Valider et filtrer les entrées en PHP. Pour les données de session dans $_SESSION, des règles propres s'appliquent ; elles figurent sur la page Sessions et cookies en PHP.
Superglobales et PHP2Shell : ce qui se passe avant votre code
Voici le lien avec la situation actuelle. CVE-2026-109618 décrit qu'un état de mémoire insuffisante (out of memory) peut interrompre PHP alors que les données de la requête ne sont que partiellement initialisées ; lors du nettoyage de la requête, des données invalides peuvent alors être traitées comme valides. Avec CVE-2026-109619, l'état interne d'une requête peut subsister après la libération de la mémoire et être utilisé par une requête ultérieure dans le même worker.
Les deux failles se situent donc dans le traitement que PHP effectue lui-même autour de la requête, non dans le code de l'application. L'équipe PHP évalue le risque comme le plus élevé avec mod_php ; un exploit y a été démontré avant même que le code de l'application ne s'exécute. Aucun filter_var() ni aucune vérification dans l'application ne peut l'empêcher.
La mise à jour vers PHP 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 et le redémarrage de tous les processus PHP sont obligatoires. Les mesures transitoires de php.net, par exemple des limites plus strictes pour post_max_size, ne constituent pas une protection complète.
Comment PHP SOS aide-t-il concrètement ?
- Nous vérifions les limites effectives pour les données de requête de chaque site web et les définissons en fonction de l'application.
- Nous installons la mise à jour de PHP, redémarrons tous les workers et prouvons le niveau de correctifs dans le cadre de notre service de correctifs PHP.
- Nous examinons les développements sur mesure pour voir si des valeurs issues de superglobales parviennent sans vérification dans la base de données, le système de fichiers ou la sortie.
- Nous sécurisons les journaux du serveur web à partir du 20/10/2026, afin qu'une analyse ultérieure reste possible.
Questions fréquentes
Combien y a-t-il de superglobales en PHP ?
Le manuel PHP en cite neuf : $GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_REQUEST et $_ENV. Elles sont disponibles dans chaque portée, y compris dans les fonctions et méthodes.
Les valeurs de $_SERVER sont-elles dignes de confiance ?
Seulement en partie. Les entrées commençant par HTTP_ proviennent des en-têtes de requête du client. Le manuel avertit par exemple que SERVER_NAME peut refléter le nom d'hôte fourni par le client et n'est pas fiable pour des décisions de sécurité.
Pourquoi $_POST est-il parfois vide alors qu'un formulaire a été envoyé ?
La cause la plus fréquente est une requête plus grande que post_max_size. Dans ce cas, selon le manuel, $_POST et $_FILES restent vides. Un réglage enable_post_data_reading désactivé y conduit aussi.
Faut-il utiliser $_REQUEST ?
Mieux vaut éviter. $_REQUEST mélange des données de différentes sources, et la source qui l'emporte dépend de request_order et de variables_order. Lisez les valeurs de façon ciblée depuis $_GET ou $_POST.