Cybersecurity

PHP2Shell: falla critica RCE in PHP, cosa fare subito

PHP2Shell: falla critica RCE in PHP, cosa fare subito

PHP2Shell è il nome dato a due vulnerabilità critiche nel motore PHP, CVE-2026-109618 e CVE-2026-109619, corrette il 21 ottobre 2026 con le release PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35. Consentono a un attaccante non autenticato di eseguire codice da remoto (RCE) sul server web, con i privilegi del processo PHP, in molti casi prima che il codice dell’applicazione venga eseguito: WordPress, Drupal, Joomla, Magento, Nextcloud o un’app Laravel non bastano a proteggersi, perché il difetto sta sotto, nell’interprete. L’Agenzia per la Cybersicurezza Nazionale ha pubblicato l’allerta AL07/261021/CSIRT-ITA con impatto sistemico alto.

In sintesi, cosa fare oggi:

  • Aggiornare PHP alla release corretta del proprio ramo (o al pacchetto patchato della propria distribuzione) e riavviare tutti i worker PHP-FPM / Apache.
  • Se non si può aggiornare subito: applicare le mitigazioni temporanee ufficiali e valutare, come raccomandano ACN e altri CERT, di mettere offline i servizi esposti fino all’aggiornamento.
  • Controllare i log per tracce di sfruttamento: errori di memoria esaurita ricorrenti, crash dei worker, processi e file inattesi.

La procedura completa, distribuzione per distribuzione, è nel tutorial dedicato: PHP2Shell fix: aggiornare PHP su Linux, Docker e Windows.

Cos’è PHP2Shell

Le due falle sono state segnalate al team PHP ad agosto 2026 da ricercatori di Calif, Wiz e OpenAI e corrette nella security release del 21 ottobre. Il resoconto tecnico dei ricercatori è su calif.io; i dettagli ufficiali sono nei due advisory GitHub del progetto PHP.

Entrambe sono use-after-free (CWE-416) con punteggio CVSS v4.0 9.2, vettore AV:N/AC:H/AT:P/PR:N/UI:N: sfruttabili via rete, senza credenziali e senza interazione dell’utente, come riportato negli advisory GHSA-w8hw-w9fx-j79w e GHSA-6wmf-4rv5-p3rp.

CVE Nome ufficiale Cosa succede
CVE-2026-109618 RCE via OOM corruption Un errore di memoria esaurita interrompe PHP mentre una struttura interna è inizializzata a metà; la pulizia di fine richiesta la tratta come valida e corrompe la memoria
CVE-2026-109619 RCE via stale global state Stato globale (errori, sessione, estensioni) sopravvive dopo che la sua memoria è stata liberata; una richiesta successiva sullo stesso worker lo riusa

CVE-2026-109618: memoria esaurita al momento sbagliato

PHP gestisce l’esaurimento di memory_limit interrompendo la richiesta con longjmp(). Se l’interruzione arriva mentre una struttura interna è stata allocata ma non ancora inizializzata, la fase di shutdown la elabora comunque. L’advisory ufficiale individua nel parsing delle richieste multipart (i normali upload di file) diversi modi per provocare l’out-of-memory a comando, restando entro i limiti di configurazione: content length assente o inutilizzabile, header illimitati per ogni parte, campi file vuoti combinati con nomi di campo annidati.

Il punto chiave: con le impostazioni predefinite (memory_limit 128M, post_max_size 8M) l’attacco è possibile, e su Apache mod_php è confermato sfruttabile. La correzione elimina il percorso con longjmp(): ora l’esaurimento di memoria viene gestito al successivo punto sicuro della VM, con un’uscita immediata del processo oltre una soglia più alta.

CVE-2026-109619: stato globale che sopravvive alla richiesta

Un worker PHP serve molte richieste in sequenza. Se un errore fatale, un timeout o un out-of-memory interrompono il reset di fine richiesta, alcuni puntatori globali restano a indicare memoria già liberata. La richiesta successiva gestita dallo stesso worker può usarli prima della normale inizializzazione, per esempio tramite il tracciamento del progresso di upload della sessione (session.upload_progress) o la gestione delle impostazioni INI per directory. Su PHP 8.5 anche i backtrace degli errori fatali possono lasciare questo stato.

Versioni di PHP vulnerabili e versioni corrette

Ramo Vulnerabile Corretto Stato del ramo
PHP 8.5 < 8.5.12 8.5.12 supportato
PHP 8.4 < 8.4.27 8.4.27 supportato
PHP 8.3 < 8.3.36 8.3.36 supportato
PHP 8.2 < 8.2.35 8.2.35 supportato (solo sicurezza)
PHP 8.1, 8.0, 7.4 tutte nessuna release ufficiale fine vita: solo backport dei sorgenti
PHP 7.3 e precedenti dal 5.4 in poi nessuna fine vita

Secondo i ricercatori, il percorso vulnerabile più vecchio risale a PHP 5.4.0 (Calif). Per i rami a fine vita il progetto PHP ha pubblicato solo backport minimi dei sorgenti per 7.4, 8.0 e 8.1, senza binari (php.net): chi usa questi rami deve affidarsi ai pacchetti della propria distribuzione (molte hanno corretto anche versioni vecchie) o migrare a un ramo supportato.

Attenzione al numero di versione. Debian, Ubuntu, RHEL e AlmaLinux applicano la correzione ai propri pacchetti senza cambiare la versione principale: un Ubuntu 24.04 aggiornato mostra ancora PHP 8.3.6 con php -v, ma è corretto. Si verifica il pacchetto, non la stringa di versione. Il tutorial spiega come.

Chi è esposto

Il progetto PHP indica come a rischio tutte le installazioni che servono richieste web: PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP e LiteSpeed (php.net). Il quadro per tipo di installazione, dagli advisory ufficiali:

  • Apache + mod_php: rischio più alto. Sfruttamento dimostrato con una singola richiesta non autenticata, prima che giri il codice dell’applicazione.
  • PHP-FPM (Nginx, Apache con proxy_fcgi): esposto in modo condizionato. Il worker FPM termina se fallisce in fase di avvio, il che blocca alcuni percorsi, ma resta sfruttabile tramite session.upload_progress e i parametri PHP_VALUE inviati dal frontend.
  • php-cgi (es. IIS/FastCGI su Windows), FrankenPHP, LiteSpeed (LSAPI): considerati probabilmente vulnerabili, anche se in configurazione predefinita non è stato dimostrato lo stesso percorso.
  • PHP da riga di comando (CLI): script e cron non servono richieste web e non sono il bersaglio, ma il pacchetto va aggiornato comunque.

I ricercatori hanno confermato la vulnerabilità, in alcuni casi con RCE pre-autenticazione, su applicazioni molto diffuse: WordPress, Drupal, Joomla, MediaWiki, Roundcube, Magento, phpMyAdmin, Nextcloud, Laravel, Symfony e WHMCS (Calif). Non sono queste applicazioni a essere difettose: è l’interprete che le esegue. Per lo stesso motivo aggiornare WordPress o i plugin non risolve PHP2Shell.

È già sfruttata? Le segnalazioni

Le fonti non concordano ancora, e conviene leggerle con attenzione:

  • Amazon ha registrato un tentativo di sfruttamento il 17 ottobre, quattro giorni prima della divulgazione, sui propri honeypot MadPot (Help Net Security).
  • Il 20 ottobre i dettagli sono trapelati prima della divulgazione coordinata (Armis); watchTowr riporta sfruttamento attivo osservato sulla propria rete di honeypot (watchTowr).
  • La scheda ACN, al 21 ottobre, non riporta PoC pubblici né sfruttamento noto, e la vulnerabilità non risulta nel catalogo KEV della CISA (ACN).

La conclusione operativa non cambia: con una falla pre-autenticazione su un componente così diffuso, i dettagli già circolati e almeno un tentativo osservato, la finestra per aggiornare va misurata in ore, non in settimane.

Cosa fare subito: la checklist

  1. Inventario. Elencare tutti i server con PHP esposto, inclusi container, hosting gestiti e appliance che includono PHP (pannelli, webmail, gestionali). Per ognuno annotare ramo, SAPI (mod_php o FPM) e distribuzione.
  2. Priorità. Prima i server esposti a Internet con mod_php, poi FPM; prima le applicazioni senza autenticazione davanti (siti pubblici, form di upload, webmail).
  3. Aggiornare al pacchetto corretto e riavviare i worker: un aggiornamento senza riavvio lascia in memoria il codice vulnerabile.
  4. Verificare il pacchetto installato (non solo php -v).
  5. Se non si può aggiornare: mitigazioni temporanee e, se il servizio non è critico, spegnerlo o metterlo dietro autenticazione.
  6. Cercare tracce di compromissione sui server rimasti esposti nei giorni scorsi.

Ogni passo, con i comandi per Debian, Ubuntu, RHEL/AlmaLinux/Rocky, Docker e Windows, è nel tutorial: PHP2Shell fix: aggiornare PHP su Linux, Docker e Windows.

Le mitigazioni temporanee (che non bastano)

Il progetto PHP è esplicito: l’unica mitigazione completa è l’aggiornamento. Le misure seguenti riducono alcuni percorsi d’attacco, non tutti (GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp):

  • session.upload_progress.enabled = 0, impostato a livello amministrativo (php.ini, pool FPM, configurazione Apache) e seguito dal riavvio di tutti i worker. Non funziona con ini_set() o .user.ini. Gli stessi sviluppatori PHP consigliano di lasciarlo disattivato anche dopo la patch, se l’applicazione non usa questa funzione.
  • memory_limit = -1 tramite php_admin_value, insieme a un limite di memoria del servizio o del container (cgroup): toglie il trigger più semplice della CVE-2026-109618, ma espone al rischio di esaurire la RAM del server. Da evitare invece RLIMIT_AS e RLIMIT_DATA, che provocano proprio l’errore di allocazione vulnerabile.
  • post_max_size contenuto (8M senza upload, 32M con upload) e limiti su dimensione della richiesta, numero di parti multipart e header sul reverse proxy o sul WAF.
  • Solo PHP 8.5: fatal_error_backtraces = 0.
  • Riduzione del rischio: pm.max_requests = 1 sui pool FPM, se le prestazioni lo consentono, perché un worker che serve una sola richiesta non può riusare stato vecchio.

Disattivare display_errors, usare l’operatore @ o cambiare error_reporting non protegge.

I principali WAF hanno pubblicato regole dedicate (Cloudflare le ha rese disponibili anche sul piano gratuito, secondo Help Net Security): utili come rete di sicurezza, non come sostituto della patch.

Leggi anche: Nginx Reverse Proxy Sicuro: Configurazione HTTPS, Header e Rate Limiting (2026)

Come accorgersi di un tentativo di attacco

ACN raccomanda, indipendentemente dalla patch, di analizzare i log per individuare (ACN):

  • richieste HTTP anomale, in particolare POST multipart molto grandi o con un numero insolito di campi;
  • errori ricorrenti Allowed memory size of ... bytes exhausted;
  • crash dei processi PHP (segmentation fault dei worker FPM o dei figli Apache);
  • esecuzione di processi inattesi da parte dell’utente del web server (www-data, apache, nginx);
  • modifiche non autorizzate ai file dell’applicazione e connessioni di rete in uscita anomale.

I comandi pronti per cercare questi segnali sono nel tutorial. Se qualcosa emerge, il server va trattato come compromesso: isolamento, analisi, credenziali ruotate. Per i soggetti NIS2 scattano gli obblighi di notifica.

Leggi anche: ACN Incidente: Checklist Notifica 24 Ore

Perché PHP2Shell è diversa dalle solite falle web

La maggior parte delle vulnerabilità che colpiscono i siti PHP sta in un plugin, in un tema o in un framework, e si chiude aggiornando quel componente. PHP2Shell sta nell’interprete: qualunque applicazione è un possibile ingresso, e i classici strumenti di difesa a livello applicativo (plugin di sicurezza, scanner di WordPress) non la vedono. È anche un caso emblematico del ruolo degli strumenti di intelligenza artificiale nella ricerca di vulnerabilità: i ricercatori dichiarano di aver usato modelli linguistici per individuare e generalizzare il difetto, che aveva radici in un problema noto da anni ma mai trasformato in un exploit (Calif).

Per chi gestisce server, la lezione pratica è una: tenere un inventario aggiornato delle versioni di runtime (PHP, ma anche Java, Node.js, Python) e un processo di patch che misuri il tempo di reazione in ore.

Leggi anche: Linux Server Hardening: Checklist 15 Punti per la Produzione (2026)

Domande frequenti su PHP2Shell

Il mio sito WordPress è vulnerabile a PHP2Shell?

Dipende dalla versione di PHP del server, non da quella di WordPress. Se il sito gira su PHP non aggiornato (qualunque ramo dal 5.4 all’8.5 senza la patch del 21 ottobre 2026), è esposto. Su hosting condiviso o gestito l’aggiornamento spetta al provider: va chiesta conferma scritta che il PHP in uso includa le correzioni per CVE-2026-109618 e CVE-2026-109619.

php -v mostra una versione vecchia: sono vulnerabile?

Non necessariamente. Le distribuzioni Linux applicano la patch senza cambiare il numero di versione principale. Si controlla la versione del pacchetto (dpkg -l o rpm -q) e il changelog alla ricerca delle due CVE.

Uso PHP 7.4 o 8.1: c’è una patch?

Il progetto PHP non rilascia binari per i rami a fine vita, ma ha pubblicato backport dei sorgenti per 7.4, 8.0 e 8.1. Ubuntu, Debian, AlmaLinux e altre distribuzioni hanno rilasciato pacchetti corretti anche per versioni vecchie, alcune solo con supporto esteso (Ubuntu Pro). La soluzione stabile resta migrare a un ramo supportato.

Basta il WAF?

No. Le regole WAF riducono il rischio mentre si aggiorna, ma i percorsi d’attacco sono più d’uno e le varianti emergeranno. L’unica correzione completa è aggiornare PHP e riavviare i worker.

Devo riavviare qualcosa dopo l’aggiornamento?

Sì: PHP-FPM e/o Apache. Finché i worker non vengono riavviati, in memoria resta il codice vulnerabile.

Fonti

Condividi questo articolo:

Scritto da

Rosario Giordano

Rosario Giordano è System Administrator e consulente IT specializzato in cybersecurity e cloud, con oltre 20 anni di esperienza nella gestione di infrastrutture Linux enterprise. Le sue aree di competenza includono hardening di SSH, piattaforme Kubernetes, database PostgreSQL, ambient i virtualizzati VMware e Proxmox, nonché la conformità ai framework di sicurezza NIS2 e ISO 27001.