Passa al contenuto

PHP2Shell: le due vulnerabilità critiche in PHP, i rischi reali e le contromisure

23 ottobre 2026 di
PHP2Shell: le due vulnerabilità critiche in PHP, i rischi reali e le contromisure
Digital Lab srl

PHP2Shell: le due vulnerabilità critiche in PHP, i rischi reali e le contromisure

Nella notte tra il 20 e il 21 ottobre 2026 il web ha vissuto una delle poche giornate che gli addetti ai lavori ricordano per anni. Due vulnerabilità nel motore di PHP — non in un plugin, non in un tema, non in un'applicazione — permettevano a una richiesta non autenticata di eseguire codice sul server. Non dietro un login, non dopo un caricamento di file: prima che una singola riga del codice applicativo venisse eseguita.

Il nome con cui sono state battezzate, PHP2Shell, descrive bene la sostanza: da una richiesta HTTP a una shell. Le due CVE, CVE-2026-109618 e CVE-2026-109619, hanno un punteggio CVSS v4.0 di 9.2. Le patch sono uscite il 21 ottobre 2026 alle 13:30 UTC nelle versioni PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35. Ma la parte che rende questo caso un caso di scuola non è la gravità: è la combinazione di tempistica, ampiezza e natura del difetto.

Questo articolo ricostruisce i fatti sulle fonti ufficiali (PHP, CERT-EU, NCSC-NL, Wiz Research, Datadog Security Labs) verificate il 23 ottobre 2026, analizza i rischi specifici per un'azienda italiana e propone contromisure immediate e strutturali, con un'attenzione particolare a WordPress e al suo ecosistema.

Che cosa è successo, in ordine

Data Evento
19 agosto 2026 Wiz Research individua la prima vulnerabilità in PHP usando strumenti AI
20–21 agosto 2026 RCE non autenticata confermata su Drupal e su WordPress
24 agosto 2026 Segnalazione al team di sicurezza PHP
17 ottobre 2026 Secondo AWS Threat Intelligence (riportato da Datadog Security Labs) iniziano tentativi di sfruttamento in the wild
20 ottobre 2026 Annuncio pubblico di un rilascio di sicurezza imminente, con dettagli che trapelano prima del previsto
21 ottobre 2026, 13:30 UTC Rilascio di PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35
21 ottobre 2026 Disclosures pubbliche, PoC in circolazione, prime regole WAF dei provider CDN

Diversi servizi pubblici hanno preferito spegnersi in via precauzionale prima della patch: tra gli altri, secondo le ricostruzioni di Patchstack, i portali olandesi DigiD e MijnOverheid e alcune piattaforme giapponesi. È un dettaglio che dice più di molte valutazioni di rischio: quando la falla è nel motore, l'alternativa tra "patch immediata" e "esposizione non mitigabile" è reale.

Le due vulnerabilità, spiegate senza gergo inutile

Entrambe nascono dallo stesso schema: un errore fatale interrompe PHP a metà di un'operazione, e una fase successiva tratta quello stato incompleto come se fosse valido.

CVE-2026-109618 — corruzione all'esaurimento della memoria. PHP converte i form inviati in $_POST. Se l'allocazione di memoria per un campo fallisce, l'operazione si interrompe ma i contatori interni risultano già aggiornati. Al momento della pulizia della richiesta, PHP incontra una struttura mai inizializzata e la interpreta: i byte residui, controllabili dall'attaccante, diventano dati che PHP esegue. Wiz ha dimostrato la catena completa su PHP 8.5.11 con un POST non autenticato, ottenendo l'esecuzione di un comando tramite la funzione di sistema della libreria C.

CVE-2026-109619 — stato globale "stantio" tra richieste. Un processo PHP (worker) serve molte richieste nel tempo. Alcune strutture interne puntano a memoria che appartiene a una singola richiesta: se PHP libera quella memoria senza azzerare il puntatore, la richiesta successiva gestita dallo stesso worker può usare un puntatore verso memoria liberata. Le varianti confermate riguardano i backtrace degli errori fatali (PHP 8.5) e l'elaborazione degli upload con il monitoraggio di avanzamento delle sessioni.

Wiz ha documentato quattro difetti concatenabili — use-after-free dell'unserializer, divulgazione di memoria del processo, use-after-free dei backtrace, type confusion di OPcache — raggruppati nelle due CVE. Il punto che li rende tutti pericolosi è lo stesso: l'exploit non richiede un errore nell'applicazione. Wiz ha dimostrato RCE pre-autenticazione sulle immagini container wordpress:latest, drupal:latest e joomla:latest, e ha osservato che anche una pagina "Hello World" su una versione vulnerabile è attaccabile.

C'è un secondo effetto, spesso sottovalutato: la divulgazione di memoria. La stessa classe di difetti consente di leggere porzioni di memoria del worker — password, token di sessione, chiavi API, certificati — senza arrivare all'esecuzione di codice. È un furto di credenziali silenzioso, che non lascia crash e non produce errori evidenti.

Perché riguarda anche chi non scrive PHP

La lista di chi è esposto è più lunga di quanto un'azienda media immagini:

  • CMS e applicazioni PHP: WordPress, Drupal, Joomla, Laravel e praticamente qualsiasi applicazione PHP in produzione.
  • SAPI diversi: PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP, LiteSpeed. PHP considera mod_php il contesto a rischio più alto, perché la richiesta malevola colpisce prima dell'esecuzione dello script.
  • Container e immagini: ogni immagine che incorpora un interprete PHP, comprese quelle costruite internamente e mai aggiornate.
  • Appliance e prodotti di terze parti che integrano PHP in pannelli di gestione o interfacce web. È il motivo per cui NCSC-NL ha pubblicato un inventario pubblico dei software potenzialmente affetti: nella lista compaiono prodotti di fornitori che stavano ancora indagando.
  • Versioni fuori supporto: Wiz indica che almeno una delle vulnerabilità colpisce ogni versione PHP dal 5.4 in poi. PHP 8.1 e precedenti non ricevono più aggiornamenti dal progetto; esistono backport minimi per 7.4, 8.0 e 8.1, oltre a pacchetti di distribuzioni e fornitori LTS.

Il messaggio operativo: il perimetro non è "il sito web", è ogni runtime PHP che risponde a richieste HTTP. Gli asset che nessuno considera infrastruttura critica sono spesso quelli più trascurati.

I rischi specifici per un'azienda

Tradurre la vulnerabilità in rischio concreto aiuta a decidere le priorità. Questi sono gli scenari plausibili, in ordine di impatto.

1. Esecuzione di codice con i privilegi del worker web. Un www-data compromesso significa shell sul server, accesso ai file dell'applicazione, lettura di wp-config.php o .env, connessione al database, scrittura di web shell persistenti. Da lì il passo verso il movimento laterale è breve, soprattutto in reti flat dove il server web può raggiungere il resto.

2. Furto di credenziali senza exploit di codice. La divulgazione di memoria espone token e chiavi presenti nel processo: credenziali del database, chiavi di servizi esterni, sessioni di altri utenti. Un'azienda può essere compromessa senza che nessun comando venga eseguito e senza segnali di crash.

3. Compromissione dei siti come vettore verso clienti e fornitori. Defacement, SEO spam, redirect verso pagine di phishing, script di skimming su un e-commerce. Il danno reputazionale e la potenziale violazione del GDPR arrivano prima della comprensione tecnica dell'incidente.

4. Hosting condiviso: blast radius moltiplicato. Su un server con cinquanta siti, una sola versione PHP non aggiornata espone tutti i tenant. Il cliente non ha visibilità né controllo su quel livello: dipende interamente dal fornitore.

5. Catena di fornitura. Immagini container, appliance, pannelli di amministrazione. NCSC-NL ha costruito un elenco di prodotti con dipendenza PHP proprio perché in questi casi l'amministratore non può aggiornare PHP direttamente: deve aspettare il fornitore.

6. Rischio normativo e contrattuale. Per i soggetti NIS, un incidente con impatto significativo attiva gli obblighi di notifica al CSIRT Italia secondo le specifiche di base definite dall'ACN. Se sono coinvolti dati personali, si aggiungono gli obblighi GDPR. Le clausole di sicurezza dei contratti con clienti enterprise prevedono sempre più spesso tempi di remediation dichiarati: non rispettarli è un inadempimento, non solo un incidente tecnico.

7. La variabile nuova: l'economia dell'exploit. Wiz dichiara di aver usato strumenti di intelligenza artificiale per trovare i difetti e costruire exploit funzionanti su più applicazioni in poche ore. Il punto non è la tecnologia in sé: è che la complessità non è più una barriera sufficiente. Difetti rimasti nascosti per oltre un decennio sono diventati sfruttabili in tempi compatibili con un'operazione offensiva ordinaria. Il tempo tra "patch disponibile" e "exploit pubblico" si misura in ore, non in settimane.

Contromisure immediate: le prime 72 ore

Queste azioni vanno eseguite adesso, non nel prossimo ciclo di patching.

1. Inventario reale dei runtime PHP

Non basta php -v sulla macchina. Servono: versione usata dal SAPI che serve le richieste, versione dentro ogni immagine container, versione degli interpreter inclusi in prodotti di terze parti, e i siti su hosting condiviso (dove la risposta è una domanda al fornitore). Datadog segnala esplicitamente il caso in cui il PHP da riga di comando è diverso da quello che serve l'applicazione.

2. Patch alle versioni corrette

  • PHP 8.5 → 8.5.12
  • PHP 8.4 → 8.4.27
  • PHP 8.3 → 8.3.36
  • PHP 8.2 → 8.2.35

Su distribuzioni Linux, i pacchetti possono contenere il fix senza cambiare il numero di versione upstream: la verifica va fatta su changelog o metadati del pacchetto (dnf updateinfo, changelog Debian/Ubuntu), non sul numero. Chi usa il repository volontario rpms.remirepo.net è stato avvisato che il fix non sarebbe stato disponibile il giorno del rilascio.

3. Riavvio dei worker e rebuild delle immagini

Applicare il pacchetto non basta se i processi continuano a girare con il codice vecchio: serve riavviare o sostituire ogni worker (reload di PHP-FPM, restart dei container). Per i container, l'aggiornamento richiede ricostruzione e ridistribuzione dell'immagine: un docker pull di un'immagine non aggiornata non risolve nulla.

4. Mitigazioni temporanee, con i loro limiti

PHP è esplicito: non esistono mitigazioni complete, aggiornare è l'unica scelta sicura. Le misure indicate riducono l'esposizione a percorsi specifici:

Per CVE-2026-109618: - impostare memory_limit=-1 in un modo che le applicazioni non possano sovrascrivere, per esempio con php_admin_value nel pool FPM o nella configurazione Apache, verificando che nessun pool, directory o applicazione reintroduca un limite finito; - abbassare post_max_size (8 MB se non servono upload, 32 MB se servono) mantenendo upload_max_filesize inferiore; - introdurre limiti a livello di web server o proxy su dimensione del corpo decodificato, numero di campi, numero di parti multipart, numero di header e profondità di annidamento, inclusi i casi senza Content-Length utilizzabile; - usare limiti di memoria di container o cgroup come confine di disponibilità, evitando RLIMIT_AS e RLIMIT_DATA che possono causare proprio l'allocazione fallita su cui si basa l'exploit.

Per CVE-2026-109619: - session.upload_progress.enabled=0 applicato in php.ini, nel pool FPM o nella configurazione del server, non con ini_set() o .user.ini, seguito dal riavvio di tutti i worker; - su PHP 8.5, fatal_error_backtraces=0, con riavvio; - rimuovere impostazioni per-richiesta obsolete o non valide che generano diagnostica prima dell'inizializzazione (nasconderle con error_reporting non serve); - correggere errori fatali e timeout raggiungibili da un attaccante.

5. Isolamento dove la patch non è possibile

CERT-EU raccomanda, se l'aggiornamento immediato non è praticabile, di isolare dall'esterno le applicazioni esposte finché il fix non è applicato e verificato. In pratica: mettere il sito in manutenzione, restringere l'accesso per IP, o filtrare al reverse proxy. Le regole WAF pubblicate da Cloudflare e da altri provider aiutano, ma valgono solo se il server accetta traffico esclusivamente attraverso quel provider: sono un tampone, non una correzione.

6. Hunting e igiene delle credenziali

I segnali da cercare, secondo Datadog e Wiz: - richieste con nomi di campo di form insolitamente lunghi (nell'esempio documentato, circa 3,5 MB) o valori contenenti byte nulli; - errori di esaurimento memoria durante l'inizializzazione della richiesta, con posizione Unknown on line 0; - segfault dei worker (per esempio AH00052 ... Segmentation fault in Apache); - cookie PHPSESSID insolitamente grandi o malformati nelle risposte; - processi shell generati da un worker web — il segnale più diretto di exploit riuscito; - riavvii inspiegati dei worker PHP.

Due trappole: un exploit riuscito può restituire HTTP 200 senza crashare nulla, e i log applicativi contengono poco perché il difetto agisce sotto il livello dell'applicazione. In caso di sospetto il server va considerato compromesso, e le credenziali che aveva in memoria vanno ruotate.

Contromisure strutturali: la pipeline e il DevSecOps

La lezione più utile di PHP2Shell è che la vulnerabilità era in una dipendenza di sistema condivisa da quasi tutto il web, non nel codice scritto dai team. Le organizzazioni che hanno reagito in ore, invece che in giorni, non avevano eroi: avevano inventario, automazione e una procedura decisionale già scritta.

Livello 1 — Sapere che cosa gira

  • SBOM per immagine e per applicazione, con la versione dell'interprete PHP come componente di primo livello, non come dettaglio del sistema operativo.
  • Base image fissate per digest, non per tag mobile come latest, così un rebuild è riproducibile e un cambio di base è una decisione, non un effetto collaterale.
  • Inventario degli asset di terze parti: appliance, pannelli, prodotti che incorporano PHP. È il punto cieco più frequente e il motivo per cui esiste l'elenco pubblico di NCSC-NL.

Livello 2 — Aggiornare con un processo, non con eroismi

  • SLA di patching per severità: critico (CVSS ≥ 9 o sfruttamento attivo) entro 24–72 ore dal fix; alto entro 14 giorni; medio entro 30–90. La metrica che conta è il tempo medio di patching, misurato.
  • Rebuild automatico delle immagini quando cambia la base, con test di fumo prima del deploy, e canary sui riavvii dei worker.
  • Finestra di manutenzione già approvata per gli aggiornamenti critici: se ogni riavvio richiede una riunione, la remediation non sarà mai rapida.

Livello 3 — Impedire che il problema rientri

  • Blocco delle versioni fuori supporto in pipeline: una regola che fallisce la build se la base image usa un ramo PHP EOL (PHP 8.2 termina il supporto di sicurezza il 31 dicembre 2026; il ramo 8.3 è il successivo a uscire).
  • Baseline di configurazione hardened come codice, versionata (memory_limit, post_max_size, upload_max_filesize, session.upload_progress, gestione degli errori) e verificata a runtime: un .user.ini o una direttiva per-richiesta possono sovrascriverla.
  • Scansione immagini e dipendenze con blocco del deploy su criticità non accettate, e un registro delle eccezioni con scadenza.
  • Gestione dei segreti fuori dall'immagine e dal repository, con rotazione periodica e a privilegio minimo: se la memoria del processo è leggibile, i segreti che vi transitano vanno considerati esposti.
  • Riduzione della superficie: disattivare gli upload dove non servono, limitare i metodi HTTP, filtrare le richieste anomale al proxy, separare i tenant su pool e container diversi.

Livello 4 — Rilevare, non solo prevenire

  • Runtime detection su processi figli dei worker web: un sh -c generato da www-data è un allarme, non un evento da ignorare.
  • Log centralizzati con conservazione adeguata e regole di correlazione tra errori di memoria, 500 ripetuti e riavvii dei worker.
  • Monitoraggio dell'integrità dei file delle applicazioni web, per intercettare web shell e modifiche non previste.
  • Threat intelligence operativa: qualcuno che legge gli avvisi di PHP, CERT-EU, ACN/CSIRT Italia e dei fornitori, con un criterio di escalation scritto (chi decide, entro quanto, con quale autorità).

Livello 5 — Governare la fornitura

  • Clausole contrattuali con tempi di remediation dichiarati e obbligo di notifica per gli incidenti che coinvolgono i dati del cliente.
  • Verifica periodica della versione di PHP sui servizi in hosting: per un sito in hosting condiviso il fornitore è l'unico che può intervenire, quindi va chiesto per iscritto, con una data.
  • Per i prodotti che incorporano PHP, seguire i bollettini del fornitore: un'appliance può restare vulnerabile anche quando la distribuzione sottostante è patchata.

Nota su WordPress: la vulnerabilità non è (solo) nei plugin

WordPress è il caso più interessante di questa vicenda, per due motivi opposti che vanno tenuti insieme.

Il primo: quanto è grande la superficie. Secondo W3Techs, al 23 ottobre 2026 WordPress è usato dal 58,3% dei siti di cui è noto il CMS, pari al 39,6% di tutti i siti web. La distribuzione per versione resta ampia (66,9% sulla 7, 26,3% sulla 6, 4,7% sulla 5, 2,0% sulla 4), e i componenti più diffusi sono Elementor (31,5% dei siti) e WooCommerce (19,8%). Sono numeri che spiegano perché una falla nel motore PHP non sia "un problema dei siti PHP": è un problema del web.

Il secondo: dove sta il difetto. PHP2Shell non è una vulnerabilità di WordPress. Wiz ha ottenuto RCE pre-autenticazione sull'immagine wordpress:latest senza sfruttare alcun bug di WordPress: il difetto è nel motore che esegue il codice, prima che WordPress venga caricato. Questo rovescia un'abitudine mentale molto diffusa: "aggiorno WordPress e i plugin, quindi sono a posto". In questo caso, un sito con core, temi e plugin perfettamente aggiornati restava completamente esposto se il provider o l'immagine container non avevano aggiornato PHP.

E qui emerge la fragilità intrinseca dell'ecosistema WordPress, che vale la pena enunciare senza eufemismi:

  1. Il livello che conta non è sotto il controllo dell'utente finale. La versione di PHP è decisa dall'hosting. Un sito su hosting condiviso dipende da una scelta tecnica presa altrove, spesso per compatibilità con applicazioni vecchie.
  2. Gli aggiornamenti automatici di plugin e temi sono opt-in. Da WordPress 5.5 l'amministratore può abilitarli per singolo plugin o tema; WordPress esegue i controlli due volte al giorno e notifica via email gli esiti. Chi non li abilita — o chi ha un hosting che li disabilita — gestisce gli aggiornamenti a mano.
  3. La superficie applicativa è enorme e distribuita. La directory ufficiale è la più grande raccolta di plugin liberi e open source per WordPress; i plugin più diffusi superano i 10 milioni di installazioni. Questo è un vantaggio per l'utente e, contemporaneamente, una superficie di attacco composta da migliaia di autori diversi, con livelli di maturità di sicurezza molto variabili.
  4. Il momento di crisi attira le scorciatoie. Patchstack ha messo in guardia esplicitamente dai "plugin fix" non ufficiali e dagli snippet copiati: non sono verificati e possono rompere il sito o peggiorare la situazione. Nelle settimane in cui la community cerca soluzioni rapide, il rischio di supply chain aumenta.
  5. Le crisi si sommano. Nello stesso periodo, sempre secondo Patchstack, un attaccante con chiavi valide del dashboard di UpdraftCentral stava installando backdoor su siti WordPress connessi. Un'ecosistema con molti componenti interconnessi produce incidenti che si sovrappongono: la compromissione di un servizio di backup diventa compromissione di centinaia di siti.

Cosa fare, in concreto, per un parco WordPress aziendale:

  • sapere quale PHP esegue davvero il sito, chiedendolo all'hosting con una data di risposta;
  • abilitare gli aggiornamenti automatici di core, plugin e temi, con backup e staging per le major;
  • ridurre i plugin al minimo, verificando manutenzione e storico di sicurezza;
  • non installare "fix" di terze parti nati durante un'emergenza;
  • filtrare al proxy o al WAF richieste con campi abnormi, sapendo che è una misura parziale;
  • monitorare integrità dei file e accessi amministrativi, con MFA obbligatoria;
  • avere un backup ripristinabile, non solo un backup esistente.

La vulnerabilità intrinseca, in sintesi, non è "WordPress è insicuro": è che WordPress è un ecosistema a più livelli — hosting, interprete, core, plugin, temi, servizi esterni — in cui l'utente controlla solo una parte dei livelli e tende a percepire come sicuro l'insieme. PHP2Shell ha colpito il livello che quasi nessuno guardava.

Quattro lezioni da portare in azienda

1. I controlli applicativi non coprono i difetti di piattaforma. Autenticazione, filtri sugli input, WAF: nulla ferma un exploit che si attiva prima del codice.

2. L'inventario è la vera contromisura. Chi sapeva quali immagini, host e appliance usavano PHP ha patchato in ore; chi non lo sapeva sta ancora cercando.

3. La velocità non si improvvisa. Un SLA senza automazione è un'intenzione; automazione senza una decisione su chi autorizza il riavvio in produzione è un blocco.

4. Il difetto è sistemico, non puntuale. La patch corregge il problema alla radice per le varianti note, ma lo schema di fondo — aggiornare i metadati prima di allocare la memoria che descrivono — può ripresentarsi.

Domande frequenti

Il mio sito è su hosting condiviso: devo fare qualcosa? Sì: verificare per iscritto con il provider versione PHP e data di applicazione della patch, chiedendo nel frattempo le mitigazioni temporanee. Se non è possibile, valutare la sospensione del sito: è una decisione commerciale, ma va presa consapevolmente.

Ho aggiornato i plugin di WordPress: sono a posto? No. PHP2Shell non sfrutta errori di WordPress né dei plugin. Serve la patch dell'interprete PHP.

Le regole WAF bastano? No. Sono un tampone utile nelle ore tra disclosure e patching, e funzionano solo se tutto il traffico passa dal provider che le applica. Non sostituiscono l'aggiornamento.

Che cosa faccio se sospetto un compromesso? Trattalo come compromesso: conserva le evidenze, ruota credenziali e chiavi che il processo poteva leggere, cerca web shell e processi inattesi, e valuta le notifiche dovute (CSIRT Italia per i soggetti NIS, Garante per i dati personali).

PHP 8.1 e precedenti: che opzioni ho? Il progetto PHP ha pubblicato backport minimi per 7.4, 8.0 e 8.1, e diverse distribuzioni o fornitori LTS hanno pacchetti corretti. Restano rami fuori supporto: la scelta strutturale è migrare a una versione supportata, tenendo conto che PHP 8.2 esce dal supporto di sicurezza il 31 dicembre 2026.

Fonti e riferimenti

Tutti i dati dell'articolo sono verificati al 23 ottobre 2026 sulle seguenti fonti primarie e tecniche:

In sintesi

PHP2Shell è stata una falla nel motore che esegue una quota enorme del web, sfruttabile senza autenticazione prima di qualsiasi codice applicativo, con impatto che va dall'esecuzione di comandi al furto silenzioso di credenziali. La patch esiste e va applicata subito, insieme al riavvio dei worker e alla ricostruzione delle immagini. Le mitigazioni temporanee riducono il rischio ma non lo eliminano.

La parte che resta dopo il patch day è organizzativa: inventario dei runtime, SLA di patching misurati, pipeline che bloccano versioni fuori supporto, baseline verificate a runtime, rilevamento dei processi anomali e fornitori sotto osservazione. È il terreno del DevSecOps: non strumenti, ma la capacità di rispondere a una criticità con un processo già collaudato.

Se vuoi costruire queste competenze — dalla gestione delle vulnerabilità alla sicurezza delle pipeline, fino al rilevamento degli incidenti — scopri i percorsi di Digital Lab su sicurezza, DevSecOps e infrastrutture.

Scopri i corsi di sicurezza e DevSecOps

Archivio