Situazione attuale: PHP2Shell. Due vulnerabilità critiche di PHP (CVSS 9,2) consentono codice dannoso senza autenticazione. Patch dal 21/10/2026.Che cosa fare ora →

Il php.ini spiegato: struttura, livelli e precedenza

Dove PHP trova le sue impostazioni, in che ordine hanno effetto e chi può sovrascriverle. Base di ogni hardening e delle misure transitorie contro PHP2Shell.

Stato 5 min di letturaConoscere PHP

In breve: il php.ini è il file di configurazione centrale di PHP. PHP lo legge all'avvio, con i moduli del server una volta, con CGI e CLI a ogni chiamata. A questo si aggiungono file supplementari da una directory di scansione, impostazioni nel pool FPM o in Apache, .htaccess o .user.ini e ini_set() nel codice. Quale livello possa modificare un valore lo stabilisce la sua modalità di modifica, ad esempio INI_SYSTEM o INI_PERDIR. I valori impostati con php_admin_value l'applicazione non può più sovrascriverli.

Che cos'è il php.ini?

Il php.ini è un file di testo con voci secondo lo schema name = wert. Stabilisce come si comporta PHP: quanta memoria può usare uno script, se gli errori compaiono nel browser, come lavorano le sessioni e quali estensioni vengono caricate. I commenti iniziano con un punto e virgola.

Secondo il manuale PHP il file viene letto all'avvio di PHP. Con i moduli del server come mod_php ciò avviene una sola volta, all'avvio del server web, con CGI e CLI a ogni chiamata. PHP-FPM legge la sua configurazione all'avvio e al ricaricamento del servizio. Una modifica senza riavvio o reload perciò di solito non ha effetto.

Da PHP 8.3, secondo il manuale, una voce può rimandare a una variabile d'ambiente con un valore sostitutivo:

memory_limit = ${PHP_MEMORY_LIMIT}
max_execution_time = ${PHP_MAX_EXECUTION_TIME:-30}

Dove cerca PHP il php.ini?

Il manuale descrive un ordine fisso. Per prima vale un percorso impostato espressamente, ad esempio PHPIniDir in Apache o l'opzione -c con CGI e CLI. Altrimenti PHP costruisce un percorso di ricerca da:

  1. la variabile d'ambiente PHPRC,
  2. su Windows la voce di registro IniFilePath,
  3. la directory di lavoro corrente, tranne che per le SAPI che lo disattivano, ad esempio la CLI,
  4. la directory del binario PHP o del modulo,
  5. il percorso impostato in compilazione --with-config-file-path.

In questo percorso di ricerca PHP cerca prima un file php-SAPI.ini, ad esempio php-cli.ini, e solo dopo php.ini. Poi PHP legge in ordine alfabetico tutti i file .ini della directory di scansione, definita tramite PHP_INI_SCAN_DIR o, in compilazione, tramite --with-config-file-scan-dir. Quali file siano stati caricati lo mostrano php --ini o la funzione php_ini_scanned_files().

php --ini
php -r 'var_dump(php_ini_loaded_file(), php_ini_scanned_files());'

Entrambi i comandi mostrano lo stato della riga di comando. Per il sito web può valere un altro file, perché ogni SAPI può avere la propria configurazione; maggiori dettagli in SAPI spiegata.

Modalità di modifica: chi può impostare quale valore?

Non ogni impostazione può essere definita ovunque. Il manuale assegna a ogni direttiva una modalità di modifica:

Modalità Dove si può impostare il valore
INI_USER negli script con ini_set(), nel registro di Windows e in .user.ini
INI_PERDIR in php.ini, .htaccess, httpd.conf o .user.ini
INI_SYSTEM solo in php.ini o httpd.conf
INI_ALL ovunque

Esempi dal manuale: memory_limit ha la modalità INI_ALL e il valore predefinito 128M, post_max_size ha INI_PERDIR e il valore predefinito 8M, upload_max_filesize ha INI_PERDIR e il valore predefinito 2M. expose_php può stare solo nel php.ini.

I file .user.ini, secondo il manuale, vengono letti solo dalle SAPI CGI e FastCGI, quindi anche da PHP-FPM. PHP li cerca dalla directory dello script verso l'alto fino al document root e li rilegge per impostazione predefinita al massimo ogni 300 secondi (user_ini.cache_ttl). Con mod_php questo ruolo è svolto da .htaccess.

Quale valore vale alla fine? I livelli in ordine di precedenza

In modo semplificato: più tardi interviene un livello, più facilmente il suo valore prevale, purché la modalità di modifica lo consenta.

  1. php.ini della rispettiva SAPI
  2. File supplementari dalla directory di scansione, in ordine alfabetico
  3. Configurazione del server: pool FPM con php_value o php_admin_value, VirtualHost di Apache
  4. Livello di directory: .htaccess con mod_php, .user.ini con FPM e CGI
  5. Runtime: ini_set() nel codice dell'applicazione

L'eccezione è decisiva: i valori impostati con php_admin_value o php_admin_flag non possono, secondo il manuale, essere sovrascritti con ini_set(). Così gli amministratori bloccano le impostazioni rilevanti per la sicurezza contro l'applicazione. La descrizione dettagliata è in php_admin_value: bloccare le impostazioni contro la sovrascrittura.

Il php.ini dopo PHP2Shell: che cosa è cambiato

Le misure transitorie di php.net contro PHP2Shell sono quasi tutte impostazioni INI: memory_limit=-1 bloccato contro la sovrascrittura, post_max_size limitato, session.upload_progress.enabled=0 e, su PHP 8.5, fatal_error_backtraces=0. php.net sottolinea che session.upload_progress.enabled non deve essere impostato tramite ini_set() o .user.ini, ma in php.ini, nel pool FPM o nella configurazione del server, con successivo riavvio di tutti i worker. L'elenco completo è in Misure immediate se non potete ancora aggiornare.

Con le versioni corrette 8.5.12, 8.4.27, 8.3.36 e 8.2.35 è cambiato, secondo il manuale, anche memory_limit: ora è un limite morbido. La nuova impostazione memory_hard_limit_percent stabilisce un limite rigido. Senza valore proprio è il doppio di memory_limit, per valori superiori a 1G il valore più 1G. Se viene superato, il processo termina subito con stato di uscita 137. Come scegliere in modo sensato i due limiti lo spiega Impostare correttamente memory_limit.

Consiglio

Secondo il manuale vale: se una versione di PHP non riconosce memory_hard_limit_percent, è interessata da CVE-2026-109618 e CVE-2026-109619. Per le distribuzioni con backport lo stato lo documenta inoltre il changelog del pacchetto.

Come aiuta concretamente PHP SOS?

  • Accertare i valori effettivi: leggiamo per ogni SAPI quali file vengono caricati e quale valore vale alla fine.
  • Riordinare i livelli: rimuoviamo le voci contraddittorie da pannelli, pool, .htaccess e .user.ini.
  • Impostare i blocchi: nell'ambito dell'hardening del server fissiamo i valori rilevanti per la sicurezza con php_admin_value.
  • Documentare: registriamo impostazioni e riavvio, perché lo stato sia in seguito dimostrabile.

Domande frequenti

Dov'è il php.ini?

Dipende da sistema operativo, pacchetto e SAPI. Su Debian e Ubuntu esistono cartelle proprie per ogni versione e SAPI, ad esempio /etc/php/8.3/fpm/php.ini e /etc/php/8.3/cli/php.ini. Da riga di comando php --ini mostra i file caricati, per il sito web aiuta php_ini_loaded_file() in un file di verifica temporaneo.

In che ordine vengono letti i file nella cartella conf.d?

Secondo il manuale PHP, PHP legge in ordine alfabetico tutti i file con estensione .ini nella directory di scansione. I file successivi sovrascrivono i valori di quelli precedenti. Per questo molti file hanno nel nome numeri come 20- o 99-.

Perché la mia modifica al php.ini non ha effetto?

Motivi frequenti: è stato modificato il file di un'altra SAPI, il servizio non è stato riavviato, un valore nel pool FPM, nella configurazione di Apache o in un .user.ini lo sovrascrive, oppure un pannello di hosting riscrive il file al salvataggio successivo.

Che cos'è memory_hard_limit_percent?

Una nuova impostazione introdotta, secondo il manuale PHP, con le release di sicurezza del 21/10/2026. Stabilisce un limite di memoria rigido come percentuale di memory_limit. Il manuale avverte che una versione di PHP che non conosce questa impostazione è interessata dalle vulnerabilità di PHP2Shell.

Fonti

Contatto immediato

Ogni ora conta. Ci scriva adesso.

Descriva brevemente sistema, versione di PHP e quanto osservato. Ci faremo sentire, chiariremo la situazione e lavoreremo da remoto fino alla chiusura e alla documentazione dell'incidente.

Aiuto immediato