Vulnerabilità PHP critica (PHP2Shell): cosa fare oggi per proteggere i tuoi siti - init.d - consulenza IT, DevOps e sviluppo software

# Vulnerabilità PHP critica (PHP2Shell): cosa fare oggi per proteggere i tuoi siti

Alessandro Corbelli~10 min
Table of Contents

Il 21 ottobre 2026 il team di sicurezza di PHP ha pubblicato aggiornamenti d’emergenza per due vulnerabilità critiche, valutate 9,2 su 10: CVE-2026-109618 e CVE-2026-109619, soprannominate PHP2Shell. Secondo l’avviso ufficiale possono permettere a chiunque, senza password e senza account, di eseguire comandi sul server che esegue PHP. Non sono falle di WordPress, di PrestaShop o di un plugin: stanno nell’interprete, il programma che esegue il codice PHP, e quindi riguardano qualunque sito o gestionale che ci gira sopra.

Se gestisci un sito, un e-commerce o un gestionale scritto in PHP, oggi ci sono tre cose da fare: capire su quale versione gira, aggiornarla, verificare che l’aggiornamento sia arrivato davvero. L’ente britannico per la sicurezza informatica (NCSC) ha invitato le organizzazioni ad agire subito e, per i sistemi che non si riescono a correggere, a valutare lo spegnimento temporaneo.

Qui sotto trovi cosa succede, chi è esposto, cosa fare in ordine, come ridurre il rischio se non puoi aggiornare oggi e come capire se qualcuno è già entrato. Le informazioni vengono dall’avviso del progetto PHP, dai due advisory pubblicati su GitHub, dal rapporto di Wiz Research, che ha scoperto le falle, e dall’NCSC, linkati in fondo. La situazione cambia in fretta: il testo fotografa le 18:00 del 21 ottobre.

Cosa è stato scoperto: due falle nella gestione degli errori di memoria

Entrambe nascono da ciò che succede quando una richiesta web muore male, in particolare quando a PHP finisce la memoria a disposizione mentre sta ancora preparando la richiesta.

  • CVE-2026-109618, corruzione di memoria da memoria esaurita: se la memoria finisce nel momento sbagliato, PHP interrompe la richiesta con un’uscita di emergenza e lascia a metà alcuni dati interni. La pulizia di fine richiesta li tratta come se fossero in ordine e ci lavora sopra. È come un magazziniere che trova un ordine preparato solo a metà, lo chiude come completo e va a toccare scaffali che non esistono.
  • CVE-2026-109619, stato residuo tra una richiesta e l’altra: un worker PHP, cioè il processo che serve le richieste e viene riutilizzato per migliaia di visitatori, può conservare riferimenti a memoria della richiesta precedente ormai liberata. La richiesta successiva li usa prima che vengano azzerati. È una lavagna non cancellata dal cliente di prima, su cui quello dopo legge e scrive credendola vuota.

Con la giusta sequenza di richieste un attaccante può leggere porzioni della memoria del server e arrivare a eseguire codice con i privilegi del web server. L’attacco passa in particolare da richieste HTTP di tipo multipart (quelle dei moduli con caricamento di file), non richiede login e non dipende dall’applicazione: Wiz ha dimostrato un’esecuzione di codice senza autenticazione sulle immagini più recenti di WordPress, Drupal e Joomla, e il progetto PHP riferisce una dimostrazione completa contro Apache con mod_php e impostazioni predefinite.

Un po’ di misura sui toni: nel punteggio ufficiale la complessità dell’attacco è indicata come alta e, secondo Wiz, l’esecuzione completa del codice richiede di concatenare più difetti e di adattarsi alla memoria del bersaglio. Non è alla portata di tutti, ma la dimostrazione esiste, e Wiz, che dichiara di aver usato modelli di IA nella ricerca, sostiene che proprio questo lavoro di adattamento sia ciò che l’IA rende più economico.

La cronologia: segnalazione al team PHP il 24 agosto, presa in carico il 21 settembre, il 20 ottobre gli identificativi delle falle trapelano online e PHP annuncia una release d’emergenza, il 21 ottobre escono le correzioni.

Chi è esposto e quali versioni sono corrette

Le versioni che correggono entrambe le falle sono PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35. Il progetto indica come a rischio le installazioni che servono richieste web: PHP-FPM, Apache con mod_php, php-cgi, FrankenPHP e LiteSpeed, con il rischio maggiore per mod_php. I soli script lanciati da riga di comando non sono il caso descritto, ma si aggiornano insieme al resto.

Le versioni vecchie sono il nodo. PHP 8.1 e precedenti non ricevono più aggiornamenti dal progetto, e Wiz stima che ogni versione fino alla 5.4 sia colpita da almeno una delle due falle. Per PHP 7.4, 8.0 e 8.1 sono state pubblicate correzioni minime del codice sorgente, utili a chi compila da sé; le distribuzioni Linux e i fornitori di supporto esteso (LTS) hanno ricevuto le patch in anticipo. È lo scenario di cui parliamo in PHP a fine vita: su una versione abbandonata ogni falla nuova resta aperta, a meno che qualcuno la corregga per te.

Non conta solo il sito. PHP gira anche dentro pannelli di controllo, gestionali, appliance e software che lo incorporano: l’NCSC chiede di censire anche questi e di seguire gli aggiornamenti dei fornitori. Su un hosting condiviso l’aggiornamento lo fa il fornitore, ed è sensato chiedergli conferma scritta invece di darla per scontata.

Cosa fare adesso: aggiornare, riavviare, verificare

  1. Inventario: elenca dove gira PHP (server, hosting, container, pannelli, software con PHP incorporato) e parti da ciò che è raggiungibile da internet. Non limitarti ai sistemi vecchi: lo chiede anche l’NCSC.
  2. Backup: prima di intervenire, una copia verificata. Sono aggiornamenti di manutenzione e il rischio di rotture è basso, ma la regola vale sempre.
  3. Aggiornamento: su un server con i pacchetti PHP della distribuzione, e poi riavvio dei servizi, perché i worker già avviati continuano a girare con il codice vecchio:
Terminal window
sudo apt update && sudo apt upgrade
sudo systemctl restart php8.3-fpm

Il nome del servizio dipende dalla versione (php8.4-fpm, php8.2-fpm); con Apache e mod_php si riavvia apache2. Sulle distribuzioni della famiglia Red Hat il comando è dnf upgrade, ma chi usa il repository esterno Remi sappia che il 21 ottobre non aveva ancora pacchetti aggiornati: la via indicata è passare ai pacchetti della distribuzione o compilare dal sorgente.

  1. Verifica vera: il numero di php -v da solo non basta. Debian ha pubblicato la correzione con il numero nuovo (su Debian 12 il pacchetto corretto è 8.2.35-1~deb12u1), mentre Ubuntu l’ha portata sulla versione che già distribuiva: su Ubuntu 24.04 la correzione è nel pacchetto 8.3.6-0ubuntu0.24.04.13, quindi php -v mostra 8.3.6, un numero che sembra più vecchio della 8.3.36 corretta, eppure il sistema è a posto. In entrambi i casi funziona il changelog del pacchetto installato, che cita i CVE:
Terminal window
zcat /usr/share/doc/php8.3-fpm/changelog.Debian.gz | grep -m2 'CVE-2026-10961[89]'

Per le immagini Docker ufficiali php: e per le installazioni compilate dal sorgente vale il contrario: il numero di versione è quello vero e deve essere almeno uno di quelli corretti. Per i container si rifà la build con docker build --pull e si controlla la versione dentro l’immagine con docker run --rm <immagine> php -v.

Se non puoi aggiornare oggi: le mitigazioni temporanee (e i loro limiti)

Il progetto PHP è netto: queste misure non rendono sicura un’installazione. Riducono la superficie, non risolvono, e servono a guadagnare qualche ora. Nel pool di PHP-FPM (su Debian e Ubuntu, /etc/php/8.3/fpm/pool.d/www.conf):

php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M
php_admin_value[session.upload_progress.enabled] = 0
; solo PHP 8.5
php_admin_value[fatal_error_backtraces] = 0

Dopo la modifica si riavviano tutti i worker. Cosa fa ciascuna riga:

  • memory_limit = -1 sembra assurdo, ma la prima falla si innesca proprio quando PHP raggiunge il limite di memoria. Il prezzo è che uno script impazzito può consumare tutta la RAM: il tetto va messo a monte, con i limiti del container o del cgroup, e non con RLIMIT_AS o RLIMIT_DATA, che provocano proprio l’errore da evitare. Si imposta con php_admin_value, che le applicazioni non possono sovrascrivere, controllando che nessun pool o cartella rimetta un limite.
  • post_max_size = 8M limita la dimensione delle richieste (32M se servono caricamenti di file, tenendo upload_max_filesize più basso). Con 8M ogni upload più grande smette di funzionare.
  • session.upload_progress.enabled = 0 spegne la barra di avanzamento degli upload, la funzione usata dalla seconda falla. Va impostata nella configurazione del server o del pool, non con ini_set() né con .user.ini, che arrivano troppo tardi. Il progetto consiglia di tenerla spenta anche dopo l’aggiornamento, se non serve.
  • fatal_error_backtraces = 0 chiude solo uno dei percorsi noti, ed esiste solo da PHP 8.5.

Davanti all’applicazione, un reverse proxy può imporre limiti alla dimensione delle richieste e, per i siti senza moduli di upload, bloccare del tutto le richieste multipart. Cloudflare ha attivato regole WAF per i vettori noti, anche sui piani gratuiti: aiutano solo se il server accetta traffico esclusivamente da Cloudflare, e Patchstack le considera un tampone. Se nessuna di queste misure è praticabile e il sistema è esposto, l’NCSC suggerisce di metterlo offline fino all’aggiornamento.

Come capire se qualcuno è già entrato

L’aggiornamento chiude la porta ma non fa uscire chi è già dentro. Le falle agiscono sotto il livello dell’applicazione, quindi i log del sito possono non mostrare quasi nulla. Gli indizi indicati da Wiz e da Huntress:

  • richieste multipart insolite seguite da errori di memoria esaurita o da serie di risposte HTTP 500;
  • cookie PHPSESSID anomali, molto grandi o malformati, nelle risposte;
  • riavvii inspiegati dei worker PHP;
  • processi del web server (php-fpm, apache2, httpd) che lanciano shell, strumenti di download come curl o wget, o comandi di ricognizione come whoami, id, uname -a.

Sul disco si cercano file PHP nuovi o modificati e attività pianificate che nessuno ha creato:

Terminal window
find /var/www -name '*.php' -mtime -3 -ls
crontab -l -u www-data

L’utente del web server è www-data su Debian e Ubuntu, apache o nginx altrove. Se trovi qualcosa: isola il server, conserva i log e non limitarti a ripulire. Una delle falle consente di leggere la memoria dei worker, quindi in un server compromesso, o anche solo sospetto, i segreti che l’applicazione teneva in memoria vanno considerati esposti: password del database, chiavi API, chiavi di sessione e di cifratura. Wiz consiglia di valutarne la rotazione. Se il server tratta dati personali e c’è un rischio per le persone, la notifica della violazione al Garante va fatta senza ingiustificato ritardo e, ove possibile, entro 72 ore: ne parliamo in GDPR lato infrastruttura.

È già sfruttata? Le fonti non coincidono

Alle 14:00 UTC del 21 ottobre Huntress dichiarava di non aver osservato sfruttamento nei sistemi dei propri partner e di non conoscere codice d’attacco pubblico (un breve video dimostrativo era stato pubblicato e poi rimosso). Nelle stesse ore Patchstack riceveva da partner di hosting segnalazioni di incidenti, ma la propria telemetria mostrava solo tentativi di sondaggio; il direttore tecnico di Cloudflare parlava di attacchi iniziali e watchTowr dichiarava tentativi sui propri sistemi esca. Nessuna di queste fonti, da sola, è conclusiva.

La lettura prudente è considerare lo sfruttamento imminente: con i dettagli pubblici e una dimostrazione funzionante, la finestra prima degli attacchi automatici di massa si misura in ore o pochi giorni.

In sintesi

Due falle critiche nel cuore di PHP, CVE-2026-109618 e CVE-2026-109619, permettono secondo il progetto di eseguire codice sul server senza autenticazione. Sono corrette in PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35, e dalle distribuzioni con pacchetti propri. Si fa l’inventario, si aggiorna, si riavviano i worker e si verifica il changelog invece del numero di versione. Dove non si può, le mitigazioni temporanee riducono la superficie ma non risolvono, e un PHP a fine vita va portato fuori da internet o migrato. Dopo l’aggiornamento si cercano tracce di accessi e, nel dubbio, si cambiano i segreti.

Fonti

Tux versione Gandalf, mascotte del blog init.d

init.d è il team di Alessandro Corbelli, sistemista Linux e sviluppatore backend con oltre vent’anni di esperienza. Progetta e gestisce infrastrutture cloud (Google Cloud, AWS, Azure), server farm e architetture ad alta disponibilità, e sviluppa software su misura in Laravel/PHP e Vue - dalla piattaforma di food delivery Take2Me ai gestionali dei nostri clienti. Su questo blog condividiamo note tecniche su Linux, sistemistica, sviluppo, DevOps ed e-commerce.


Altri articoli