Questa guida spiega come correggere PHP2Shell (CVE-2026-109618 e CVE-2026-109619) su un server reale: capire quale PHP serve davvero il sito, aggiornarlo su Debian, Ubuntu, RHEL/AlmaLinux/Rocky, Docker e Windows, verificare che la correzione sia attiva, applicare le mitigazioni se non si può aggiornare subito e cercare tracce di attacco. Per il contesto della vulnerabilità vedi l’analisi: PHP2Shell: falla critica RCE in PHP, cosa fare subito.
Le versioni corrette pubblicate dal progetto PHP il 21 ottobre 2026 sono 8.5.12, 8.4.27, 8.3.36 e 8.2.35 (php.net). Le distribuzioni Linux applicano la stessa correzione ai propri pacchetti con numeri di versione diversi: la tabella al passo 3 riporta quelli da cercare.
Tempo richiesto: 15-30 minuti per server. Serve accesso root o sudo.
Passo 1 – Capire quale PHP serve il sito
Su molti server convivono più versioni di PHP, e il comando php -v mostra solo quella da riga di comando (CLI), che può essere diversa da quella usata dal web server. Bisogna individuare la SAPI in uso (mod_php o PHP-FPM) e il relativo pacchetto.
# Versione CLI (indicativa, non decisiva)
php -v
# Apache con mod_php? (Debian/Ubuntu: apache2ctl, RHEL: httpd)
apache2ctl -M 2>/dev/null | grep -i php
httpd -M 2>/dev/null | grep -i php
# Servizi PHP-FPM attivi
systemctl list-units --type=service --state=running | grep -i fpm
# Pacchetti PHP installati
dpkg -l 'php*' 2>/dev/null | awk '/^ii/{print $2, $3}' # Debian/Ubuntu
rpm -qa 'php*' 2>/dev/null | sort # RHEL/AlmaLinux/Rocky
Il metodo più affidabile è chiedere a PHP stesso, attraverso il web server. Creare un file temporaneo con un nome non indovinabile, aprirlo nel browser e cancellarlo subito:
F="/var/www/html/check-$(openssl rand -hex 6).php"
echo '<?php echo PHP_VERSION, " | ", PHP_SAPI, " | upload_progress=", ini_get("session.upload_progress.enabled"), " | ", php_ini_loaded_file();' | sudo tee "$F"
echo "Apri: https://tuosito.it/$(basename "$F")"
# dopo averlo letto:
sudo rm -f "$F"
L’output, ad esempio 8.3.6 | fpm-fcgi | upload_progress=1 | /etc/php/8.3/fpm/php.ini, dice quale versione, quale SAPI e quale php.ini usa davvero il sito. apache2handler significa mod_php: è la configurazione a rischio più alto, da aggiornare per prima.
Passo 2 – Aggiornare PHP su Debian e Ubuntu
Aggiornare tutti i pacchetti PHP installati, senza toccare il resto del sistema:
sudo apt update
dpkg -l 'php*' | awk '/^ii/{print $2}' | xargs sudo apt-get install --only-upgrade -y
Su Ubuntu 20.04 e precedenti le correzioni arrivano solo tramite Ubuntu Pro (ESM): senza abbonamento attivo apt non troverà aggiornamenti. Si attiva con sudo pro attach (gratuito per uso personale fino a 5 macchine).
Chi usa i pacchetti di Ondřej Surý (ppa:ondrej/php su Ubuntu, packages.sury.org su Debian) riceve le versioni originali del progetto PHP: dopo l’aggiornamento php -v deve mostrare almeno 8.2.35, 8.3.36, 8.4.27 o 8.5.12. Se il repository non le ha ancora pubblicate, applicare le mitigazioni del passo 6 nell’attesa.
Passo 3 – Verificare il pacchetto corretto su Debian e Ubuntu
Le distribuzioni applicano la patch senza cambiare la versione principale: Ubuntu 24.04 aggiornato mostra ancora PHP 8.3.6. Si verifica la versione del pacchetto e il changelog:
# Versione installata (sostituire 8.3 con il proprio ramo)
dpkg -l php8.3-common | awk '/^ii/{print $2, $3}'
# Il changelog deve citare le due CVE
zcat /usr/share/doc/php8.3-common/changelog.Debian.gz | grep -m2 -E 'CVE-2026-10961[89]'
Versioni minime corrette, da Debian Security Tracker e Ubuntu Security:
| Distribuzione | Pacchetto | Versione corretta (o successiva) |
|---|---|---|
| Debian 13 trixie | php8.4 | 8.4.27-1~deb13u1 (DSA-6574-1) |
| Debian 12 bookworm | php8.2 | 8.2.35-1~deb12u1 |
| Ubuntu 26.10 | php8.5 | 8.5.9-0ubuntu2.1 |
| Ubuntu 26.04 LTS | php8.5 | 8.5.4-0ubuntu1.5 |
| Ubuntu 24.04 LTS | php8.3 | 8.3.6-0ubuntu0.24.04.13 |
| Ubuntu 22.04 LTS | php8.1 | 8.1.2-1ubuntu2.28 |
| Ubuntu 20.04 LTS (Pro/ESM) | php7.4 | 7.4.3-4ubuntu2.29+esm5 |
| Ubuntu 18.04 LTS (Pro/ESM) | php7.2 | 7.2.24-0ubuntu0.18.04.17+esm14 |
Passo 4 – Aggiornare PHP su RHEL, AlmaLinux e Rocky Linux
sudo dnf clean metadata
sudo dnf upgrade 'php*'
# Verifica: versione del pacchetto e changelog
rpm -q php-common
rpm -q --changelog php-common | grep -m2 -E 'CVE-2026-10961[89]'
Su AlmaLinux 10 con PHP 8.4 i pacchetti si chiamano php8.4-* (verifica con rpm -q php8.4-common). Anche qui la versione principale resta quella della distribuzione: AlmaLinux, ad esempio, ha corretto PHP 8.3 nel pacchetto php-8.3.33-1.el10_2.alma.1 (AlmaLinux). Su RHEL 9 il modulo php:8.2 passa alla 8.2.35.
Su AlmaLinux/RHEL 8 il flusso predefinito è PHP 7.2, ormai fuori supporto da anni: è il momento di passare a un flusso recente.
dnf module list php
sudo dnf module reset php
sudo dnf module enable php:8.2
sudo dnf distro-sync 'php*'
Il cambio di versione principale va provato prima su un ambiente di test: estensioni e applicazioni vecchie possono non essere compatibili.
Chi usa il repository Remi: al 21 ottobre non aveva ancora pubblicato aggiornamenti, e il progetto PHP suggerisce di passare ai pacchetti della distribuzione o di compilare dai sorgenti (Help Net Security). Controllare con dnf check-update 'php*' e, finché non arriva la patch, applicare il passo 6.
Passo 5 – Riavviare i worker (passo obbligatorio)
L’aggiornamento dei file su disco non basta: i processi PHP già in esecuzione continuano a usare il codice vulnerabile finché non vengono riavviati. Con PHP2Shell conta doppio, perché la CVE-2026-109619 sfrutta proprio lo stato lasciato nei worker.
# Debian/Ubuntu (un servizio per ogni versione installata)
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2 # se mod_php o Apache davanti a FPM
# RHEL/AlmaLinux/Rocky
sudo systemctl restart php-fpm
sudo systemctl restart httpd
# Controllo: l'orario di avvio dei processi deve essere successivo all'aggiornamento
ps -eo pid,lstart,cmd | grep -E 'php-fpm|apache2|httpd' | grep -v grep
Infine ripetere il controllo via web del passo 1 (e cancellare di nuovo il file).
Docker
Le immagini ufficiali php compilano la versione originale del progetto: basta ricostruire con un tag corretto e ricreare i container.
# Fissare la versione corretta nel Dockerfile
FROM php:8.4.27-fpm
docker compose build --pull
docker compose up -d
docker compose exec app php -v # deve mostrare 8.4.27 o superiore
Le immagini di terze parti (applicazioni pronte, stack LAMP) vanno aggiornate quando il produttore pubblica la nuova versione: controllare la versione di PHP all’interno del container con php -v.
Windows (IIS o Apache)
Scaricare la build corretta da windows.php.net, sostituire la cartella di PHP mantenendo il proprio php.ini e riavviare il servizio: iisreset per IIS (o il riciclo dell’application pool), il riavvio del servizio Apache negli altri casi. Su IIS PHP gira come php-cgi tramite FastCGI, una delle modalità indicate come esposte.
Hosting condiviso e pannelli
Su hosting gestito, cPanel o Plesk l’aggiornamento di PHP spetta al provider o al pannello. Verificare la versione con il file di test del passo 1 e, se non è corretta, aprire un ticket chiedendo conferma esplicita della patch per CVE-2026-109618 e CVE-2026-109619.
Passo 6 – Mitigazioni se non puoi aggiornare subito
Le mitigazioni riducono il rischio ma non chiudono la falla: il progetto PHP dichiara che l’unica mitigazione completa è l’aggiornamento (GHSA-6wmf-4rv5-p3rp). Se il servizio non è indispensabile, ACN e altri CERT consigliano di metterlo offline fino alla patch.
Le impostazioni vanno applicate a livello amministrativo: ini_set() e .user.ini non funzionano, perché l’attacco avviene prima che quei valori vengano letti.
PHP-FPM, nel file del pool (es. /etc/php/8.3/fpm/pool.d/www.conf):
; Toglie il trigger confermato della CVE-2026-109619 (tenerlo anche dopo la patch, se non serve)
php_admin_flag[session.upload_progress.enabled] = off
; Limiti prudenti sulle richieste
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 6M
; Solo PHP 8.5
php_admin_flag[fatal_error_backtraces] = off
; Opzionale: un worker per richiesta, niente stato riutilizzabile (costa prestazioni)
pm.max_requests = 1
Apache con mod_php, nel VirtualHost o in apache2.conf:
php_admin_flag session.upload_progress.enabled off
php_admin_value post_max_size 8M
php_admin_value upload_max_filesize 6M
LimitRequestBody 8388608
LimitRequestFields 50
memory_limit = -1 toglie il trigger più semplice della CVE-2026-109618, ma da solo espone il server all’esaurimento della RAM. Se lo si adotta, va abbinato a un limite di memoria del servizio, ad esempio con sudo systemctl edit php8.3-fpm:
[Service]
MemoryMax=2G
Non usare invece RLIMIT_AS o RLIMIT_DATA (ad esempio ulimit -v): secondo l’advisory provocano proprio l’errore di allocazione che rende sfruttabile la falla (GHSA-w8hw-w9fx-j79w).
Sul reverse proxy Nginx: limitare la dimensione delle richieste e, dove l’applicazione non prevede upload, bloccare le richieste multipart:
client_max_body_size 8m;
# Solo dove non servono upload: blocca i POST multipart
if ($http_content_type ~* "multipart/form-data") {
return 403;
}
Dopo ogni modifica: sudo nginx -t, sudo apachectl configtest, poi riavvio dei servizi PHP e del web server. Con mod_php verificare il valore effettivo con il file di test del passo 1.
Leggi anche: Nginx Reverse Proxy Sicuro: Configurazione HTTPS, Header e Rate Limiting (2026)
Passo 7 – Cercare tracce di attacco
I dettagli sono circolati prima della divulgazione e un tentativo di sfruttamento è stato osservato il 17 ottobre (Help Net Security): sui server rimasti esposti conviene cercare i segnali indicati da ACN. Adattare i percorsi dei log al proprio sistema.
# Errori di memoria esaurita (trigger della CVE-2026-109618)
sudo grep -h "Allowed memory size of" /var/log/php*fpm*.log /var/log/apache2/error.log* \
/var/log/httpd/error_log* /var/log/nginx/error.log* 2>/dev/null | tail -n 50
# Crash dei worker PHP
sudo grep -hE "exited on signal (11|6)|SIGSEGV" /var/log/php*fpm*.log 2>/dev/null
sudo grep -h "Segmentation fault" /var/log/apache2/error.log* /var/log/httpd/error_log* 2>/dev/null
sudo journalctl -k --since "2026-10-15" | grep -iE "segfault.*(php|apache2|httpd)"
# POST terminati con errore 500/502 (formato log combined)
sudo awk '$6 ~ /POST/ && ($9 == 500 || $9 == 502)' /var/log/nginx/access.log /var/log/apache2/access.log 2>/dev/null | tail -n 50
# Processi lanciati dal web server (shell, wget, curl, python...)
ps -eo user,pid,ppid,lstart,cmd --forest | grep -A3 -E "php-fpm|apache2|httpd" | grep -vE "php-fpm|apache2|httpd|grep"
# File PHP creati o modificati di recente nella webroot
sudo find /var/www -type f -name "*.php" -newermt "2026-10-15" -printf "%TY-%Tm-%Td %TH:%TM %p\n" | sort
# Connessioni in uscita dei processi web
sudo ss -tpn state established | grep -E "php-fpm|apache2|httpd"
Qualche errore di memoria isolato è normale su siti con molto traffico; contano le raffiche dallo stesso indirizzo IP, i crash concentrati in pochi minuti, i processi figli che non dovrebbero esistere (una shell sotto www-data) e i file PHP comparsi nelle cartelle di upload. In presenza di questi segnali il server va trattato come compromesso: isolarlo, conservare log e immagine del disco, ruotare credenziali e chiavi usate dalle applicazioni. Per i soggetti NIS2 valgono gli obblighi di notifica.
Leggi anche: ACN Incidente: Checklist Notifica 24 Ore
Checklist finale
- Individuati tutti i server e i container con PHP esposto, con SAPI e versione
- Aggiornati i pacchetti PHP (o le immagini Docker)
- Verificati versione del pacchetto e changelog con le due CVE
- Riavviati PHP-FPM e/o Apache; controllato l’orario di avvio dei processi
- Controllato via web che versione e SAPI siano quelle attese; file di test cancellato
session.upload_progress.enableddisattivato se l’applicazione non lo usa- Log analizzati dal 15 ottobre in poi
- Pianificata la migrazione dei server con PHP fuori supporto (8.1 e precedenti)
Leggi anche: Linux Server Hardening: Checklist 15 Punti per la Produzione (2026)
Fonti
- PHP – October 2026 Security Release (8.5.12, 8.4.27, 8.3.36, 8.2.35)
- PHP Security Advisory GHSA-w8hw-w9fx-j79w – CVE-2026-109618
- PHP Security Advisory GHSA-6wmf-4rv5-p3rp – CVE-2026-109619
- ACN / CSIRT Italia – AL07/261021/CSIRT-ITA
- Debian Security Tracker – CVE-2026-109618
- Ubuntu Security – CVE-2026-109618
- AlmaLinux – php2shell: patched PHP packages released