In breve: le superglobali sono array predefiniti che PHP riempie automaticamente a ogni richiesta e che sono disponibili ovunque nel codice. $_GET contiene i parametri dell'indirizzo, $_POST i dati del modulo, $_FILES i file caricati, $_COOKIE i cookie e $_SERVER le informazioni su richiesta e server. PHP crea questi array prima che parta il codice della Sua applicazione. Perciò le vulnerabilità proprio in questa elaborazione, come con PHP2Shell, non possono essere intercettate da controlli nell'applicazione.
Che cosa sono le superglobali?
In PHP una variabile normalmente vale solo nella funzione in cui è stata creata. Le superglobali sono l'eccezione: sono disponibili in ogni ambito di validità, senza doverle recuperare con global. Il manuale PHP ne cita nove.
Per i non tecnici si può descrivere così: le superglobali sono la cassetta delle lettere dell'applicazione. Tutto ciò che un visitatore invia finisce lì, prima che l'applicazione lo legga. E tutto ciò che sta nella cassetta delle lettere proviene potenzialmente da un estraneo.
Le superglobali in sintesi
| Superglobale | Contenuto | Origine |
|---|---|---|
$_GET |
parametri dell'indirizzo (query string) | client |
$_POST |
campi del modulo di una richiesta POST | client |
$_FILES |
informazioni sui file caricati | client, elaborate da PHP |
$_COOKIE |
cookie inviati dal browser | client |
$_REQUEST |
miscela di GET, POST e se del caso cookie | client |
$_SERVER |
header di richiesta, metodo, percorsi, informazioni sul server | server web e client mescolati |
$_ENV |
variabili d'ambiente | server |
$_SESSION |
dati della sessione corrente | memoria del server |
$GLOBALS |
tutte le variabili globali | script |
$_SERVER è particolarmente insidiosa. Secondo il manuale PHP crea per ogni header di richiesta una voce che inizia con HTTP_, ad esempio HTTP_USER_AGENT. Questi valori li imposta il client stesso. Anche SERVER_NAME può, secondo il manuale, contenere il nome host fornito dal client e non è affidabile per decisioni di sicurezza.
Come PHP riempie le superglobali
Prima che venga eseguito il primo carattere del Suo script, PHP ha già lavorato. Legge l'indirizzo, gli header e il contenuto della richiesta, li scompone e deposita i risultati negli array. Diverse impostazioni controllano questo passaggio:
variables_order(predefinitoEGPCS) stabilisce quali superglobali vengano create del tutto: Environment, GET, POST, Cookie, Server.request_order(predefinito vuoto) determina da che cosa si formi$_REQUEST. Se è vuoto valevariables_order. I file php.ini forniti omettono, secondo il manuale, i cookie per ragioni di sicurezza.max_input_vars(predefinito1000) emax_input_nesting_level(predefinito64) limitano numero e annidamento delle variabili di input.post_max_size(predefinito8M) limita il contenuto della richiesta. Se una richiesta è più grande,$_POSTe$_FILESrestano vuoti.enable_post_data_reading(predefinito attivo) controlla se PHP elabori automaticamente il contenuto delle richieste POST.
Se enable_post_data_reading è disattivato, l'applicazione legge da sé il contenuto grezzo tramite php://input. Da PHP 8.4.0 esiste inoltre request_parse_body(), che elabora dati di moduli e upload anche per metodi diversi da POST e consente limiti propri. Come si svolga nel dettaglio la parte degli upload lo spiega la pagina Come PHP elabora gli upload di file.
Gestire in sicurezza i dati della richiesta
Il principio è semplice: ogni valore proveniente da $_GET, $_POST, $_COOKIE, $_FILES e dalle voci HTTP_ di $_SERVER è un input estraneo. Va verificato all'acquisizione e opportunamente neutralizzato all'output.
<?php
declare(strict_types=1);
// Atteso un numero intero: verificare invece di convertire alla cieca
$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');
}
// Ammettere solo valori consentiti
$sortierung = in_array($_GET['sort'] ?? '', ['name', 'datum'], true)
? $_GET['sort']
: 'datum';
// Neutralizzare sempre l'output
echo htmlspecialchars($_POST['kommentar'] ?? '', ENT_QUOTES, 'UTF-8');
Un ostacolo frequente sono le indicazioni sull'origine di una richiesta. Se davanti al server web c'è un reverse proxy, un load balancer o una CDN, $_SERVER['REMOTE_ADDR'] contiene l'indirizzo di questo intermediario, non quello del visitatore. L'indirizzo reale sta allora in un header come X-Forwarded-For, che però ogni client può impostare da sé. L'applicazione deve valutare tali header solo se la richiesta proviene dimostrabilmente da un proprio proxy noto. Altrimenti i blocchi per indirizzo IP o i log si lasciano ingannare facilmente. Qualcosa di simile vale per HTTPS: se la cifratura termina sul proxy, l'applicazione deve sapere espressamente che la connessione originaria era cifrata.
Altri modelli per validazione e filtraggio li mostra l'articolo Validare e filtrare gli input in PHP. Per i dati di sessione in $_SESSION valgono regole proprie, descritte nella pagina Sessioni e cookie in PHP.
Superglobali e PHP2Shell: che cosa accade prima del Suo codice
Qui sta il nesso con la situazione attuale. CVE-2026-109618 descrive come una condizione di memoria esaurita (out-of-memory) possa interrompere PHP mentre i dati della richiesta sono inizializzati solo in parte; nella pulizia della richiesta i dati non validi possono poi essere trattati come validi. Con CVE-2026-109619 lo stato interno di una richiesta può rimanere dopo la liberazione della memoria ed essere usato da una richiesta successiva nello stesso worker.
Entrambe le vulnerabilità si trovano dunque nell'elaborazione che PHP stesso svolge intorno alla richiesta, non nel codice dell'applicazione. Il team PHP classifica per mod_php il rischio più alto; lì è stato dimostrato un exploit prima ancora che giri codice dell'applicazione. Nessun filter_var() e nessun controllo nell'applicazione può impedirlo.
È obbligatorio l'aggiornamento a PHP 8.5.12, 8.4.27, 8.3.36 o 8.2.35 e il riavvio di tutti i processi PHP. Le misure transitorie di php.net, ad esempio limiti più stretti per post_max_size, non sono una protezione completa.
Come aiuta concretamente PHP SOS?
- Verifichiamo i limiti effettivi per i dati della richiesta per ogni sito web e li impostiamo in modo adatto all'applicazione.
- Installiamo l'aggiornamento di PHP, riavviamo tutti i worker e documentiamo lo stato delle patch nell'ambito del nostro servizio di patch PHP.
- Esaminiamo gli sviluppi su misura per vedere se valori delle superglobali finiscano senza controllo nel database, nel file system o nell'output.
- Mettiamo al sicuro i log del server web dal 20/10/2026, perché resti possibile una successiva analisi.
Domande frequenti
Quante superglobali esistono in PHP?
Il manuale PHP ne cita nove: $GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_REQUEST e $_ENV. Sono disponibili in ogni ambito di validità, anche in funzioni e metodi.
I valori in $_SERVER sono affidabili?
Solo in parte. Le voci che iniziano con HTTP_ provengono dagli header di richiesta del client. Il manuale avverte ad esempio che SERVER_NAME può riflettere il nome host fornito dal client e non è affidabile per decisioni di sicurezza.
Perché $_POST a volte è vuoto anche se un modulo è stato inviato?
La causa più frequente è una richiesta più grande di post_max_size. In tal caso $_POST e $_FILES restano, secondo il manuale, vuoti. Porta a questo anche l'impostazione enable_post_data_reading disattivata.
Si dovrebbe usare $_REQUEST?
Meglio di no. $_REQUEST mescola dati di fonti diverse e quale fonte prevalga dipende da request_order e variables_order. Legga i valori in modo mirato da $_GET o $_POST.