En resumen: los superglobales son arrays predefinidos que PHP rellena automáticamente en cada petición y que están disponibles en todo el código. $_GET contiene los parámetros de la dirección, $_POST los datos de formularios, $_FILES los archivos subidos, $_COOKIE las cookies y $_SERVER datos sobre la petición y el servidor. PHP crea estos arrays antes de que se inicie el código de su aplicación. Por eso, las vulnerabilidades de justo este procesamiento, como en PHP2Shell, no pueden interceptarse con comprobaciones en la aplicación.
¿Qué son los superglobales?
En PHP, una variable normalmente solo vale en la función en la que se creó. Los superglobales son la excepción: están disponibles en cualquier ámbito, sin necesidad de obtenerlos con global. El manual de PHP menciona nueve.
Para quienes no son técnicos puede describirse así: los superglobales son el buzón de la aplicación. Todo lo que envía un visitante acaba allí antes de que la aplicación lo lea. Y todo lo que hay en el buzón procede potencialmente de un desconocido.
Los superglobales de un vistazo
| Superglobal | Contenido | Origen |
|---|---|---|
$_GET |
parámetros de la dirección (query string) | cliente |
$_POST |
campos de formulario de una petición POST | cliente |
$_FILES |
datos sobre los archivos subidos | cliente, preparados por PHP |
$_COOKIE |
cookies enviadas por el navegador | cliente |
$_REQUEST |
mezcla de GET, POST y, en su caso, cookies | cliente |
$_SERVER |
cabeceras de la petición, método, rutas, datos del servidor | servidor web y cliente mezclados |
$_ENV |
variables de entorno | servidor |
$_SESSION |
datos de la sesión actual | almacenamiento del servidor |
$GLOBALS |
todas las variables globales | script |
$_SERVER es especialmente traicionero. Según el manual, PHP genera para cada cabecera de la petición una entrada que empieza por HTTP_, por ejemplo HTTP_USER_AGENT. Estos valores los fija el propio cliente. También SERVER_NAME puede contener, según el manual, el nombre de host suministrado por el cliente y no es fiable para decisiones de seguridad.
Cómo rellena PHP los superglobales
Antes de que se ejecute el primer carácter de su script, PHP ya ha trabajado. Lee la dirección, las cabeceras y el contenido de la petición, los descompone y guarda los resultados en los arrays. Varios ajustes controlan este paso:
variables_order(por defectoEGPCS) determina qué superglobales se crean: Environment, GET, POST, Cookie, Server.request_order(por defecto vacío) determina de qué se forma$_REQUEST. Si está vacío, rigevariables_order. Según el manual, los archivos php.ini incluidos omiten las cookies por motivos de seguridad.max_input_vars(por defecto1000) ymax_input_nesting_level(por defecto64) limitan el número y el anidamiento de las variables de entrada.post_max_size(por defecto8M) limita el contenido de la petición. Si una petición es mayor,$_POSTy$_FILESquedan vacíos.enable_post_data_reading(por defecto activado) controla si PHP evalúa automáticamente el contenido de las peticiones POST.
Si enable_post_data_reading está desactivado, la aplicación lee por su cuenta el contenido en bruto mediante php://input. Desde PHP 8.4.0 existe además request_parse_body(), que evalúa datos de formularios y de cargas también para métodos distintos de POST y permite límites propios. Cómo funciona en detalle la parte de las cargas lo explica la página Cómo procesa PHP las cargas de archivos.
Tratar con seguridad los datos de la petición
El principio es sencillo: todo valor de $_GET, $_POST, $_COOKIE, $_FILES y de las entradas HTTP_ de $_SERVER es una entrada ajena. Se comprueba al recibirlo y se aplica el escape adecuado al emitirlo.
<?php
declare(strict_types=1);
// Se espera un entero: comprobar en lugar de convertir a ciegas
$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');
}
// Admitir solo valores permitidos
$sortierung = in_array($_GET['sort'] ?? '', ['name', 'datum'], true)
? $_GET['sort']
: 'datum';
// Aplicar siempre el escape a la salida
echo htmlspecialchars($_POST['kommentar'] ?? '', ENT_QUOTES, 'UTF-8');
Un obstáculo frecuente son los datos sobre el origen de una petición. Si delante del servidor web hay un proxy inverso, un balanceador de carga o una CDN, $_SERVER['REMOTE_ADDR'] contiene la dirección de ese intermediario, no la del visitante. La dirección real figura entonces en una cabecera como X-Forwarded-For, que cualquier cliente puede fijar por su cuenta. La aplicación solo debe evaluar estas cabeceras si la petición procede demostrablemente de un proxy propio y conocido. Si no, los bloqueos por dirección IP o los registros pueden engañarse con facilidad. Algo parecido rige para HTTPS: si el cifrado termina en el proxy, la aplicación debe saber expresamente que la conexión original iba cifrada.
Más patrones de validación y filtrado los muestra el artículo Validar y filtrar entradas en PHP. Para los datos de sesión en $_SESSION rigen reglas propias; están en la página Sesiones y cookies en PHP.
Superglobales y PHP2Shell: lo que ocurre antes de su código
Aquí está la relación con la situación actual. CVE-2026-109618 describe que un estado de falta de memoria puede interrumpir PHP mientras los datos de la petición solo están inicializados en parte; al limpiar la petición, los datos no válidos pueden tratarse entonces como válidos. En CVE-2026-109619, el estado interno de una petición puede persistir tras liberar la memoria y ser utilizado por una petición posterior en el mismo worker.
Ambas vulnerabilidades están, por tanto, en el procesamiento que realiza el propio PHP en torno a la petición, no en el código de la aplicación. El equipo de PHP considera que el riesgo es mayor en mod_php; allí se demostró un exploit antes de que se ejecute siquiera código de la aplicación. Ningún filter_var() ni comprobación en la aplicación puede evitarlo.
Es obligatoria la actualización a PHP 8.5.12, 8.4.27, 8.3.36 o 8.2.35 y el reinicio de todos los procesos de PHP. Las medidas provisionales de php.net, como límites más estrictos para post_max_size, no son una protección completa.
¿Cómo ayuda PHP SOS en concreto?
- Comprobamos los límites efectivos de los datos de la petición de cada sitio web y los ajustamos a la aplicación.
- Instalamos la actualización de PHP, reiniciamos todos los workers y demostramos el estado del parche en el marco de nuestro servicio de parcheo de PHP.
- Revisamos los desarrollos propios para ver si valores de los superglobales llegan sin comprobar a la base de datos, al sistema de archivos o a la salida.
- Aseguramos los registros del servidor web a partir del 20/10/2026 para que siga siendo posible una evaluación posterior.
Preguntas frecuentes
¿Cuántos superglobales hay en PHP?
El manual de PHP menciona nueve: $GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_REQUEST y $_ENV. Están disponibles en cualquier ámbito, también en funciones y métodos.
¿Son fiables los valores de $_SERVER?
Solo en parte. Las entradas que empiezan por HTTP_ proceden de las cabeceras de la petición del cliente. El manual advierte, por ejemplo, de que SERVER_NAME puede reflejar el nombre de host suministrado por el cliente y no es fiable para decisiones de seguridad.
¿Por qué $_POST a veces está vacío aunque se haya enviado un formulario?
La causa más frecuente es una petición mayor que post_max_size. Entonces, según el manual, $_POST y $_FILES quedan vacíos. También lo provoca un ajuste enable_post_data_reading desactivado.
¿Debería usarse $_REQUEST?
Mejor no. $_REQUEST mezcla datos de distintas fuentes y cuál prevalece depende de request_order y variables_order. Lea los valores de forma específica desde $_GET o $_POST.