PHP2Shell è una coppia di vulnerabilità critiche nel motore stesso di PHP, CVE-2026-109618 e CVE-2026-109619, pubblicate il 21 ottobre 2026 con una gravità CVSS di 9.2. Su un runtime non aggiornato, un attaccante privo di account può eseguire codice come worker PHP o leggere la memoria del processo, che contiene password, token di sessione, chiavi API e certificati. Non serve che il codice della sua applicazione contenga un bug: secondo i ricercatori, anche una semplice pagina “Hello World” su una versione di PHP vulnerabile può essere esposta. L’unica vera soluzione è una release di PHP corretta, seguita dal riavvio di ogni processo che esegue PHP. Questa guida le fornisce i comandi.
Quali versioni sono corrette
| Ramo | Vulnerabile | Corretto in |
|---|---|---|
| 8.2 | inferiore a 8.2.35 | 8.2.35 |
| 8.3 | inferiore a 8.3.36 | 8.3.36 |
| 8.4 | inferiore a 8.4.27 | 8.4.27 |
| 8.5 | inferiore a 8.5.12 | 8.5.12 |
PHP 8.1, 8.0 e 7.x hanno raggiunto la fine del ciclo di vita e non riceveranno alcuna correzione. Se li usa ancora, la patch consiste nel passare a un ramo supportato.
Le distribuzioni Linux spesso riportano le correzioni di sicurezza nei propri pacchetti (backport) senza passare al numero di versione upstream. Su questi sistemi la versione da sola non basta: cerchi i due identificativi CVE nel changelog del pacchetto (passo 2).
Passo 1: trovare ogni runtime PHP
Cominci dall’inventario, perché il runtime di cui nessuno si ricordava è proprio quello che viene colpito. Su ogni server:
php -v
systemctl list-units --type=service --all 'php*' 'apache2*' 'httpd*'
ls /usr/sbin/php-fpm* /usr/bin/php[0-9]* 2>/dev/null
La prima riga mostra la versione della CLI, la seconda i pool PHP-FPM e i server web in esecuzione, la terza ogni versione di PHP installata in parallelo (una fonte frequente di runtime dimenticati). Elenchi anche i pacchetti installati:
dpkg -l 'php*' | grep '^ii' # Debian, Ubuntu
rpm -qa 'php*' 'ea-php*' # RHEL, AlmaLinux, Rocky, cPanel
Per i container, verifichi la versione di PHP all’interno di ogni immagine in esecuzione:
docker ps --format '{{.Names}}' | while read c; do printf '%s: ' "$c"; docker exec "$c" php -r 'echo PHP_VERSION, PHP_EOL;' 2>/dev/null || echo 'no php'; done
Non dimentichi i server di staging, cron e code, gli agent di build e i piani di hosting gestito. Se usa un piano di hosting, chieda per iscritto al provider quale build di PHP sta usando e quando è stata aggiornata.
Passo 2: installare la release corretta
Debian e Ubuntu (sostituisca 8.3 con il suo ramo):
sudo apt update
sudo apt install --only-upgrade 'php8.3*'
apt changelog php8.3-fpm | grep -E 'CVE-2026-10961[89]'
RHEL, AlmaLinux, Rocky Linux:
sudo dnf upgrade 'php*'
rpm -q --changelog php-fpm | grep -E 'CVE-2026-10961[89]'
Server cPanel con pacchetti EasyApache 4:
sudo dnf upgrade 'ea-php*' # older systems: sudo yum update 'ea-php*'
Alpine Linux (i nomi dei pacchetti contengono il ramo, ad esempio php83):
apk update && apk upgrade 'php83*'
Immagini Docker: fissi il tag corretto nel Dockerfile, ad esempio FROM php:8.3.36-fpm, poi ricostruisca senza cache e sostituisca i container in esecuzione:
docker build --pull --no-cache -t myapp:php2shell .
docker compose up -d --build --force-recreate
Se il grep sul changelog non restituisce nulla, la sua distribuzione non ha ancora rilasciato la correzione. Continui a controllare, usi la release ufficiale di php.net dove compila PHP in proprio e, nel frattempo, applichi le misure temporanee descritte più sotto.
Passo 3: riavviare tutto ciò che ha caricato il vecchio PHP
Un nuovo pacchetto non cambia nulla nei processi già in esecuzione. Li riavvii:
sudo systemctl restart php8.3-fpm # Debian, Ubuntu (one per installed version)
sudo systemctl restart php-fpm # RHEL family
sudo systemctl restart apache2 # Apache with mod_php (httpd on RHEL)
sudo supervisorctl restart all # long-running workers under Supervisor
php artisan queue:restart # Laravel queue workers
Su Debian e Ubuntu, sudo needrestart -r l elenca i servizi che usano ancora vecchie librerie.
Passo 4: verificare
Controlli di nuovo ogni runtime, questa volta quello usato dal server web, non solo la CLI:
php-fpm8.3 -v # or: php-fpm -v
systemctl status php8.3-fpm | grep Active
La versione deve essere pari o superiore alla release corretta (oppure il changelog del pacchetto deve riportare entrambe le CVE), e l’orario di “Active: since” deve essere successivo all’aggiornamento. Su WordPress può leggere la versione anche in Strumenti, Salute del sito, Info, Server. Non pubblichi online una pagina phpinfo() per verificarlo: rivela esattamente ciò che cercano gli attaccanti.
Quando l’aggiornamento deve aspettare
Queste impostazioni indicate dai ricercatori riducono l’esposizione mentre prepara l’aggiornamento. Non sono una correzione:
; php.ini
post_max_size = 8M ; as low as your uploads allow
max_input_nesting_level = 32 ; as low as your forms allow
session.upload_progress.enabled = 0
fatal_error_backtraces = 0 ; where your PHP version supports it
; PHP-FPM pool: recycle workers more often (costs performance)
pm.max_requests = 100
I valori sono esempi; li testi con la sua applicazione. Impostare memory_limit = -1 blocca alcuni percorsi di attacco, ma lo usi solo insieme a un limite a livello di sistema operativo come memory.max di cgroup v2, e non sostituisca mai questo limite con RLIMIT_AS o RLIMIT_DATA. Le regole WAF e CDN del suo provider aiutano come soluzione ponte, non come sostituto dell’aggiornamento.
Cercare segni di un attacco
Non esiste un’unica regola di rilevamento. Questi comandi fanno emergere i segnali descritti dai ricercatori:
grep -E 'Allowed memory size of [0-9]+ bytes exhausted' /var/log/php*-fpm.log /var/log/apache2/error.log
grep -E 'exited on signal (6|11)' /var/log/php*-fpm.log
awk '$9 == 500' /var/log/nginx/access.log | wc -l
Errori di limite di memoria dopo richieste multipart insolite, raffiche di risposte HTTP 500, worker PHP che vanno in crash per un segnale e cookie PHPSESSID insolitamente grandi nelle risposte meritano un’analisi più attenta. Nessuno di questi segni prova un attacco, e la loro assenza non prova che lei non sia stato colpito. Se li trova, conservi i log, applichi la patch e ruoti i segreti che risiedevano nella memoria di PHP: password dei database, chiavi applicative e token API. Il nostro team di risposta agli incidenti può prendere in carico l’indagine, e il nostro servizio di sicurezza gestita può monitorare i suoi server dopo la patch.
Da dove iniziare
- Esegua i comandi di inventario su ogni server e container e annoti ogni versione di PHP.
- Aggiorni con il suo gestore di pacchetti o ricostruisca le immagini su un tag corretto.
- Riavvii PHP-FPM, Apache e ogni worker PHP.
- Verifichi la versione e l’orario del riavvio, e conservi l’output come prova.
- Cerchi con grep nei log i segni descritti sopra e ruoti i segreti su ogni sistema in cui compaiono.
Dettagli: sito dell’advisory PHP2Shell, annuncio della PHP Foundation, Wiz Research.

