Situación actual: PHP2Shell. Dos vulnerabilidades críticas de PHP (CVSS 9.2) permiten ejecutar código malicioso sin autenticación. Parches desde el 21/10/2026.Qué hacer ahora →

Superglobales: $_GET, $_POST, $_FILES y otros

Los superglobales son los arrays mediante los cuales el código PHP accede a los datos de la petición. Quien sabe cómo los rellena PHP y qué límites rigen escribe código más seguro y entiende mejor PHP2Shell.

Actualizado 5 min de lecturaConocimiento de PHP

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:

  1. variables_order (por defecto EGPCS) determina qué superglobales se crean: Environment, GET, POST, Cookie, Server.
  2. request_order (por defecto vacío) determina de qué se forma $_REQUEST. Si está vacío, rige variables_order. Según el manual, los archivos php.ini incluidos omiten las cookies por motivos de seguridad.
  3. max_input_vars (por defecto 1000) y max_input_nesting_level (por defecto 64) limitan el número y el anidamiento de las variables de entrada.
  4. post_max_size (por defecto 8M) limita el contenido de la petición. Si una petición es mayor, $_POST y $_FILES quedan vacíos.
  5. 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.

Actuar de inmediato

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.

Fuentes

Contacto inmediato

Cada hora cuenta. Escríbanos ahora.

Describa brevemente el sistema, la versión de PHP y lo que ha observado. Nos pondremos en contacto, aclararemos la situación y trabajaremos en remoto hasta que el incidente quede cerrado y documentado.

Ayuda inmediata