PHP2Shell: cosa sono le due falle critiche di PHP, come controllare se sei esposto e come aggiornare

Due RCE critiche in PHP, senza autenticazione, già cercate in rete. Versioni corrette, pacchetti delle distribuzioni, immagini Docker, come usare il checker di OpenAI e cosa fare se non puoi aggiornare stasera, dalle fonti ufficiali.

Francesco Pio Nocerino8 minNovità
PHP2Shell: cosa sono le due falle critiche di PHP, come controllare se sei esposto e come aggiornare
Indice

In breve: PHP2Shell è il nome di due vulnerabilità critiche di PHP, CVE-2026-109618 e CVE-2026-109619, entrambe 9,2 su CVSS 4.0. Permettono di eseguire codice da remoto senza autenticazione su PHP che serve richieste web: PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP e LiteSpeed. Le correzioni sono uscite il 21 ottobre alle 16:00 (ora italiana): PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35. Debian, Ubuntu e le immagini Docker ufficiali hanno già i pacchetti aggiornati. watchTowr e Cloudflare segnalano tentativi di sfruttamento in rete. Se hai un sito in PHP, aggiorna stasera; le mitigazioni riducono il rischio ma, secondo lo stesso team di PHP, non rendono sicura l'installazione.

Questo pezzo si basa solo su fonti primarie lette il 21 ottobre 2026 sera: l'advisory di php.net, i due advisory su GitHub, i tracker di Debian e Ubuntu, Docker Hub, il repository del checker di OpenAI, gli avvisi di CISA, Cloudflare e watchTowr. Non ho eseguito il checker né riprodotto le vulnerabilità: comandi e significato dei risultati vengono dal README.

Cosa sono le due vulnerabilità

L'advisory di php.net le descrive così:

  • CVE-2026-109618, RCE via OOM corruption (GHSA-w8hw-w9fx-j79w). Quando PHP esaurisce la memoria (out of memory), può interrompersi mentre i dati interni della richiesta sono inizializzati solo in parte. La pulizia di fine richiesta li tratta poi come validi. L'advisory elenca diversi modi per arrivare all'esaurimento della memoria restando dentro i limiti apparenti, quasi tutti nel parsing delle richieste multipart.
  • CVE-2026-109619, RCE via stale global state (GHSA-6wmf-4rv5-p3rp). Uno stato interno legato a una richiesta sopravvive dopo che la sua memoria è stata liberata. Una richiesta successiva gestita dallo stesso worker può usarlo prima della normale inizializzazione: è un use-after-free.

Il rischio più alto, per il team di PHP, è su mod_php: c'è un exploit dimostrato in cui una richiesta non autenticata fa scattare l'attacco prima che parta il codice dell'applicazione. Su mod_php, quindi, non conta quale CMS o framework usi: il problema è nel runtime, e WordPress, Drupal, Laravel o uno script scritto a mano sono nella stessa posizione. Su FPM, l'advisory di CVE-2026-109618 dice che l'analisi del codice lo indica come vulnerabile, anche se non è stato dimostrato un exploit completo.

Il blog di Cloudflare attribuisce la scoperta a Calif, Wiz, OpenAI e Quarkslab. I dettagli sono trapelati il 20 ottobre e PHP ha anticipato di un giorno la data concordata, come avevamo riportato nelle notizie di cybersecurity del 21 ottobre.

Chi è colpito

Tutte le installazioni PHP che servono richieste web, su qualunque ramo non aggiornato. I due advisory su GitHub indicano come vulnerabili le versioni precedenti a 8.2.35, 8.3.36, 8.4.27 e 8.5.12. Il checker di OpenAI considera vulnerabili anche i rami vecchi, fino all'ultima release di ciascuno:

Ramo PHP

Versione corretta

Note

8.5

8.5.12

Supportato

8.4

8.4.27

Supportato

8.3

8.3.36

Supportato

8.2

8.2.35

Supportato

8.1, 8.0, 7.4

Nessuna release ufficiale

Solo backport minimi del codice sorgente da php.net, o pacchetti del vendor

7.3 e precedenti, fino a 5.4

Nessuna

Il checker li segna vulnerabili fino all'ultima versione del ramo

Per i rami fuori supporto, php.net dice che il progetto non pubblica più aggiornamenti: alcune distribuzioni e alcuni vendor LTS hanno pacchetti con le correzioni riportate, altrimenti bisogna passare a una versione supportata.

Come controllare: il checker di OpenAI

Il repository openai/php2shell-checker esiste ed è ufficiale: è nell'organizzazione GitHub di OpenAI, ha licenza Apache 2.0, è stato creato il 21 ottobre e l'ultimo commit, firmato e verificato, è del 21 ottobre alle 20:05 (ora italiana). OpenAI non accetta contributi di codice esterni, solo segnalazioni.

Cosa fa. Confronta una versione di PHP con una tabella di soglie scritta nel codice (aggiornata al 20 ottobre). La versione la prende in due modi: dagli header HTTP Server e X-Powered-By di un sito, oppure dall'output di php -v sulla macchina locale. Non manda exploit, non segue redirect e non legge il corpo delle risposte.

Come si usa, dal README. Serve Node.js. Per un sito:

node phpcheck.js "https://example.com"

Per il PHP installato sulla macchina:

node phpcheck.js --local

Con --json l'output è leggibile da script, con il campo patch_status. Nel codice ci sono anche --php per indicare un eseguibile diverso e --timeout per le richieste HTTP. Il README propone anche due skill per Codex, phpcheck-url e phpcheck-server, da installare con $skill-installer.

Cosa significano i risultati, sempre dal README:

Risultato

Codice di uscita

Significato

OK

0

Versione stabile sopra la soglia del suo ramo

VULNERABLE

1

Versione uguale o inferiore alla soglia

UNKNOWN

3

Versione non trovata, ramo non riconosciuto o build di sviluppo

Argomenti sbagliati danno codice 2.

I limiti, che il README stesso mette in chiaro:

  • UNKNOWN non vuol dire che sei al sicuro. Se il server nasconde la versione negli header, che è una buona pratica, il controllo via URL non può dirti niente.
  • OK è solo un confronto di numeri di versione: non verifica che la correzione ci sia davvero.
  • I pacchetti delle distribuzioni spesso riportano la correzione senza cambiare la versione upstream. Su Ubuntu 24.04, per esempio, la versione corretta è 8.3.6-0ubuntu0.24.04.13: il checker legge 8.3.6 e la segna VULNERABLE anche se il pacchetto è aggiornato. In quel caso vale il tracker della distribuzione, non il checker.
  • php -v mostra il PHP da riga di comando, che può non essere quello che serve il sito via FPM o Apache. La skill phpcheck-server chiede di verificare che coincidano.

In pratica: il checker è utile per un inventario veloce di molti siti, ma la prova vera è la versione del pacchetto installato confrontata con l'advisory del vendor.

Come aggiornare

Da sorgente o binari Windows. Le release 8.5.12, 8.4.27, 8.3.36 e 8.2.35 sono sulla pagina dei download di PHP. Per 7.4, 8.0 e 8.1 il team di PHP ha pubblicato backport minimi del codice sorgente, per chi compila da sé e non ha un vendor LTS.

Debian. Il security tracker indica come corretti php8.4 8.4.27-1~deb13u1 su trixie (DSA-6574-1) e php8.2 8.2.35-1~deb12u1 su bookworm (DLA-4848-1). Su forky e sid, al momento della lettura, il pacchetto risulta ancora non corretto.

Ubuntu. Gli avvisi sono USN-8948-1 e USN-8948-2. Il tracker di Ubuntu indica come corretti, tra gli altri:

  • 26.04 LTS: php8.5 8.5.4-0ubuntu1.5
  • 24.04 LTS: php8.3 8.3.6-0ubuntu0.24.04.13
  • 22.04 LTS: php8.1 8.1.2-1ubuntu2.28
  • 20.04, 18.04, 16.04 e 14.04: correzioni disponibili solo con Ubuntu Pro

Per vedere quale pacchetto hai installato:

dpkg -l 'php*'     # Debian e Ubuntu
rpm -qa 'php*'     # Red Hat, Fedora, AlmaLinux, Rocky

Su Red Hat e derivate lo stato dei pacchetti è sulla pagina della CVE di Red Hat.

Remi. php.net avverte che il repository volontario rpms.remirepo.net non avrà aggiornamenti il 21 ottobre: chi lo usa dovrebbe passare ai pacchetti della distribuzione o compilare da sorgente.

Docker. Su Docker Hub le immagini ufficiali php hanno i tag 8.5.12, 8.4.27, 8.3.36 e 8.2.35, comprese le varianti -fpm e -apache, pubblicate il 21 ottobre in serata. Se il tuo Dockerfile parte da php:8.3-fpm o simili, non basta riavviare il container: devi rifare la build con l'immagine nuova e ridistribuire.

docker pull php:8.3.36-fpm
docker build --pull -t mio-sito .

Hosting condiviso. Se il PHP lo gestisce il provider, chiedi conferma scritta che abbia aggiornato. Se il pannello ti fa scegliere la versione, passa a un ramo supportato.

Se non puoi aggiornare stasera

php.net elenca alcune misure che riducono l'esposizione a percorsi specifici ma non rendono sicura l'installazione. Vanno impostate in php.ini, nella pool FPM o nella configurazione del server, non con ini_set() né con .user.ini, e richiedono il riavvio di tutti i worker:

  • Per CVE-2026-109619: session.upload_progress.enabled=0. Blocca i percorsi confermati attraverso le sessioni, non altre varianti. Su PHP 8.5 anche fatal_error_backtraces=0.
  • Per CVE-2026-109618: memory_limit=-1, possibilmente con php_admin_value in modo che l'applicazione non possa cambiarlo, insieme a un limite di memoria a livello di container o cgroup per non far cadere il server. php.net sconsiglia di usare RLIMIT_AS o RLIMIT_DATA al suo posto, perché possono provocare proprio l'errore di allocazione vulnerabile.
  • Richieste più piccole: post_max_size = 8M se l'applicazione non ha upload, 32M se li ha, con upload_max_filesize più basso. Dove possibile, limiti anche sul web server o sul proxy per dimensione delle richieste, numero di campi e di parti multipart.

Nascondere gli errori con display_errors o error_reporting non serve, scrive php.net.

WAF. Cloudflare ha attivato regole WAF contro PHP2Shell dal 21 ottobre alle 05:02 (ora italiana), anche sul piano gratuito, e dice di aver visto traffico di attacco. Proteggono solo il traffico che passa da Cloudflare: se l'origine è raggiungibile direttamente dall'IP, un attaccante può aggirarle. Cloudflare stessa chiede di aggiornare comunque. Se usi già un WAF davanti al sito, vale la pena ricontrollare anche le regole di rate limiting.

Se non puoi fare niente di tutto questo, CISA consiglia di togliere dalla rete i sistemi che non si possono aggiornare, compresi quelli su PHP 8.1 o precedenti.

Lo stato dello sfruttamento

  • watchTowr, nella sua FAQ, dice di aver osservato tentativi di sfruttamento il 21 ottobre sulla sua rete di honeypot.
  • Cloudflare ha visto traffico di attacco già prima del rilascio delle patch e attaccanti che modificavano il payload per aggirare le regole.
  • CISA, nell'alert del 21 ottobre, dice di non aver osservato sfruttamento al momento della pubblicazione. Al controllo della sera del 21 ottobre, le due CVE non risultavano nel catalogo KEV.

La differenza tra "tentativi" e "compromissioni confermate" conta: per ora le fonti primarie parlano di tentativi. Non aspetterei la conferma per aggiornare.

Dopo l'aggiornamento

Un exploit di questo tipo porta all'esecuzione di codice con i permessi del worker PHP, e CVE-2026-109619 può anche esporre memoria del processo. CISA consiglia di controllare se ci sono worker PHP che avviano shell o scaricano strumenti. Se il sito è rimasto esposto e non aggiornato da ieri, conviene anche:

  • controllare i file modificati di recente nelle cartelle del sito;
  • ruotare le chiavi API e le password lette dall'applicazione, come spiegato in segreti, .env e chiavi API;
  • tenere da parte i log del web server delle ultime 48 ore.

Se il sito è nato con un agente e non sai neanche quale PHP gira, la checklist per portare in produzione un sito vibe coded è un buon punto da cui ripartire. E se gestisci il server da solo su una VPS, questo è il lato meno visibile della scelta discussa in Vercel, Cloudflare o VPS: le patch di sicurezza tocca a te farle.

Cosa conviene fare adesso

  • Fai l'elenco di tutti i server, container e hosting dove gira PHP, anche quelli dimenticati.
  • Aggiorna a 8.5.12, 8.4.27, 8.3.36 o 8.2.35, oppure al pacchetto corretto della tua distribuzione; nei container rifai la build.
  • Controlla la versione del pacchetto installato confrontandola con il tracker della distribuzione; usa il checker di OpenAI per un primo giro su molti siti, sapendo che UNKNOWN non è un via libera.
  • Se resti su PHP 8.1 o precedenti, pianifica la migrazione: nel frattempo, mitigazioni e WAF, o il sito fuori rete.
  • Riavvia tutti i worker dopo l'aggiornamento e verifica che giri la versione nuova.
  • Se il sito era esposto, controlla file e processi e ruota i segreti.
[ DOMANDE FREQUENTI ]

Domande frequenti

01Cos'è PHP2Shell?

È il nome di due vulnerabilità critiche di PHP, CVE-2026-109618 e CVE-2026-109619, corrette il 21 ottobre 2026. Permettono a un attaccante non autenticato di eseguire codice sul server tramite richieste HTTP costruite apposta. Riguardano il runtime di PHP, non un CMS o un framework in particolare.

02Quali versioni di PHP correggono PHP2Shell?

PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35. Per 7.4, 8.0 e 8.1 il team di PHP ha pubblicato solo backport minimi del codice sorgente; per quei rami servono i pacchetti di una distribuzione o di un vendor LTS, oppure il passaggio a una versione supportata.

03Il checker di OpenAI dice UNKNOWN: sono al sicuro?

No. UNKNOWN significa che il checker non ha trovato la versione, per esempio perché il server la nasconde negli header. Il README lo dice esplicitamente. Controlla la versione del pacchetto installato sul server.

04Uso WordPress: devo aggiornare WordPress o PHP?

PHP. Le vulnerabilità sono nel runtime e, su mod_php, l'attacco scatta prima che parta il codice dell'applicazione. Aggiornare WordPress e i plugin resta utile, ma non corregge PHP2Shell.

05Il WAF di Cloudflare basta a proteggermi?

No. Cloudflare ha attivato regole contro PHP2Shell anche sul piano gratuito, ma le definisce una protezione temporanea e chiede di aggiornare. Le regole proteggono solo il traffico che passa da Cloudflare, non chi raggiunge l'origine direttamente.

06Ubuntu ha aggiornato PHP ma il checker dice VULNERABLE: perché?

Perché Ubuntu applica la correzione alla versione che distribuisce senza cambiare il numero upstream: per esempio 8.3.6 su Ubuntu 24.04. Il checker confronta solo il numero e la segna vulnerabile. Se il pacchetto installato corrisponde alla versione corretta indicata nel tracker di Ubuntu, sei aggiornato.

Condividi