php2shell-checker di OpenAI è un buon punto di partenza, ma da solo non dimostra che un server sia sicuro. Il tool confronta la versione di PHP ricavata dagli header HTTP o da php -v con alcune soglie di versione integrate. Per questo un header nascosto può restituire UNKNOWN, mentre un backport della distribuzione può far apparire vulnerabile un server già corretto.
Parti dai possibili risultati
Il repository ufficiale di OpenAI restituisce tre stati principali. Considerali segnali di triage, non una valutazione completa della vulnerabilità.
| Output | Codice di uscita | Che cosa indica | Prossima azione |
|---|---|---|---|
OK | 0 | Il ramo riconosciuto è alla versione minima corretta o a una versione successiva | Verifica che il processo PHP che gestisce il traffico web utilizzi quella versione |
VULNERABLE | 1 | La versione rilevata è precedente alla versione minima corretta | Aggiorna il runtime che serve il sito, riavvia i worker ed esegui di nuovo entrambi i controlli |
UNKNOWN | 3 | Il checker non è riuscito a stabilire una versione o una risposta riconosciuta | Controlla il server localmente; non considerarlo corretto |
| Argomenti non validi | 2 | Il comando non era valido | Correggi il comando ed eseguilo di nuovo |
Che cosa include il pacchetto di OpenAI
Il repository pubblico php2shell-checker contiene uno script Node.js, i test e due skill per Codex: phpcheck-url per un sito raggiungibile e phpcheck-server per un server a cui hai accesso. Il tool raccoglie gli indizi sulla versione; non sfrutta il target e non analizza il codice dell'applicazione.
Esegui il controllo nella modalità corretta
Controllare un URL pubblico
Clona o scarica il repository, poi avvia lo script Node.js passando l'indirizzo del sito:
node phpcheck.js "https://example.com"
Il controllo remoto invia una richiesta HTTP HEAD e passa a GET solo se il server restituisce 405 o 501. Legge gli header X-Powered-By e Server, non segue i redirect e non analizza il corpo della risposta.
Un CDN, un reverse proxy, expose_php=off o una configurazione personalizzata del server possono rimuovere la versione di PHP prima che la risposta arrivi al checker. Un risultato VULNERABLE richiede un aggiornamento; se l'header manca, servono invece riscontri locali.
Controllare un binario PHP locale
Su una macchina con PHP installato, usa:
node phpcheck.js --local
Il comando esegue php -v sul binario disponibile nel PATH corrente. Questo non dimostra che lo stesso binario serva il sito: sullo stesso host possono coesistere installazioni separate per CLI, PHP-FPM, CGI, modulo Apache, container o compilazione dai sorgenti.
Dopo il controllo locale, individua il runtime collegato al web server. In un deployment containerizzato, controlla il container in esecuzione e non soltanto il tag dell'immagine. Se usi un servizio fornito da un pacchetto, verifica il pool PHP-FPM o il modulo Apache interessato, insieme al changelog del pacchetto del vendor.
Installare e usare le skill di Codex
Il README ufficiale installa entrambe le skill con un unico comando Codex:
$skill-installer install both skills from https://github.com/openai/php2shell-checker
Poi scegli l'interfaccia in base al tipo di accesso che hai:
$phpcheck-url check https://example.com
$phpcheck-server check the PHP version serving my site
Codex è opzionale. Il comando Node.js resta l'interfaccia diretta per i job CI e gli host essenziali. Per l'automazione, aggiungi --json: il campo patch_status restituisce ok, vulnerable o unknown, evitando di dover analizzare il testo mostrato nel terminale.
Verificare il checker scaricato
Il repository utilizza il test runner integrato in Node:
node --test phpcheck.test.js
La suite esegue il CLI contro server HTTP locali e usa un eseguibile PHP fittizio per gli scenari locali. Secondo il README, non servono né un'installazione reale di PHP né l'accesso a un sito esterno.
Considera UNKNOWN un risultato di diagnostica
Tratta UNKNOWN come un'indicazione incompleta. Il target potrebbe nascondere la versione di PHP, usare un ramo non riconosciuto, non rispondere oppure eseguire una prerelease più recente: nessuno di questi casi dimostra che la correzione sia presente.
Un utente reale, @jvr0x, ha riassunto così il limite:
“È solo un confronto di versione con le soglie del 20 ottobre, quindi gli header nascosti restituiscono UNKNOWN.”
Il comando remoto vede una risposta HTTP, non il processo che si trova dietro il reverse proxy. Se l'header è nascosto, devi controllare il server invece di ripetere le richieste all'URL.
Dopo un risultato UNKNOWN, procedi così:
- Esegui
node phpcheck.js --localsull'host che serve il sito. - Verifica se la richiesta raggiunge PHP-FPM, CGI,
mod_phpdi Apache o un container. - Controlla il changelog del pacchetto del vendor per individuare eventuali backport.
- Dopo l'aggiornamento, riavvia i worker PHP-FPM o Apache interessati.
- Verifica il percorso che serve effettivamente il sito, non soltanto il binario
phppredefinito della shell.
Senza SSH, la modalità URL potrebbe essere l'unico controllo iniziale disponibile. Se un hosting condiviso nasconde l'header della versione, sarà il provider a dover confermare il runtime in uso, la revisione del pacchetto e l'avvenuto riavvio.
La tabella delle versioni non basta per decidere se una patch è presente
Il checker considera PHP 8.5.12, 8.4.27, 8.3.36 e 8.2.35 le versioni upstream minime corrette per i rispettivi rami. I test ufficiali confermano che 8.4.26 è VULNERABLE, mentre 8.4.27 è OK; PHP identifica 8.5.12, 8.4.27, 8.3.36 e 8.2.35 come versioni di sicurezza.
| Ramo | Versione upstream minima corretta | Versione precedente classificata come vulnerabile |
|---|---|---|
| PHP 8.5 | 8.5.12 | 8.5.11 |
| PHP 8.4 | 8.4.27 | 8.4.26 |
| PHP 8.3 | 8.3.36 | 8.3.35 |
| PHP 8.2 | 8.2.35 | 8.2.34 |
| Situazione del deployment | Perché un semplice confronto di versioni può trarre in inganno | Riscontro da utilizzare |
|---|---|---|
Header X-Powered-By o Server nascosto | Il checker remoto non riesce a identificare PHP | Inventario del runtime locale |
| Pacchetto di sicurezza Debian o Ubuntu | Il vendor può aver applicato il fix come backport mantenendo una versione upstream precedente | Advisory del vendor e changelog del pacchetto |
| PHP-FPM e CLI sullo stesso host | php -v potrebbe descrivere la CLI e non il worker HTTP | Configurazione del web server e di FPM |
| Container in cache o digest bloccato | Il tag del registry può essere aggiornato mentre il container in esecuzione è ancora vecchio | ID dell'immagine del container in esecuzione e versione |
| Worker Apache o FPM non riavviati | I file corretti possono essere presenti sul disco mentre i worker più vecchi restano attivi | Orario di avvio del processo e controllo successivo al riavvio |
| Ramo non supportato o prerelease | Il checker potrebbe non riconoscere lo stato della patch applicata dal vendor | Avviso di sicurezza di PHP o del vendor |
La sezione dedicata ai limiti del repository spiega che lo strumento presume che le versioni stabili successive di un ramo elencato contengano la correzione, ma non può verificarla in modo indipendente. Una distribuzione può applicare un security backport senza modificare il numero di versione upstream: in questi casi il changelog è una prova più solida del solo numero visualizzato.
Aggiornare WordPress, Drupal, Laravel o un'altra applicazione PHP non corregge il motore PHP. Aggiorna il pacchetto o l'immagine del runtime, riavvia i worker e verifica il processo che accetta le richieste web.
FAQ
Quale output permette di chiudere un ticket di remediation in produzione?
Nessun output dovrebbe chiudere da solo un ticket. Affianca OK alla verifica del SAPI che serve il sito, dello stato dei backport del vendor, di tutti i vhost o container interessati e del riavvio dei worker dopo l'applicazione della patch.