In breve: php_admin_value e php_admin_flag impostano le configurazioni PHP nel pool PHP-FPM o nella configurazione di Apache in modo che le applicazioni non possano modificarle né con ini_set() né con .htaccess. php.net richiede proprio questo per le misure transitorie di PHP2Shell, ad esempio per memory_limit=-1. Dopo l'impostazione il servizio deve essere riavviato e il valore va verificato nel contesto web.
Perché «impostato» non significa «bloccato»
Nei giorni successivi al 21 ottobre 2026 molti amministratori hanno scritto nel proprio php.ini le misure transitorie di php.net. Un dettaglio della raccomandazione è spesso passato inosservato: memory_limit=-1 deve essere impostato in modo che le applicazioni non possano sovrascriverlo. php.net indica a tal fine espressamente php_admin_value nel pool FPM o nella configurazione di Apache.
Il motivo è semplice. Molti CMS, shop e framework impostano valori propri, ad esempio un limite di memoria più alto per le importazioni. Se il valore sta solo in php.ini, l'applicazione lo sovrascrive alla chiamata successiva. La misura di protezione esiste allora sulla carta, ma non nel processo in esecuzione.
Questo non riguarda solo PHP2Shell. Ogni hardening, dagli output di errore disattivati ai limiti di upload, è forte solo quanto il suo livello più debole.
Chi può in generale modificare le impostazioni PHP
PHP conosce quattro modalità di modifica. Ogni impostazione ne ha una, ed essa determina in quali punti può essere impostata. I significati provengono dal manuale PHP.
| Modalità | Dove si può impostare il valore | Esempi |
|---|---|---|
INI_USER |
nello script con ini_set() e in .user.ini |
pochi valori di runtime |
INI_PERDIR |
php.ini, .htaccess, httpd.conf, .user.ini |
post_max_size, session.upload_progress.enabled |
INI_SYSTEM |
solo php.ini o httpd.conf |
file_uploads, disable_functions |
INI_ALL |
ovunque, anche con ini_set() |
memory_limit, display_errors, open_basedir |
Pericolosi sono soprattutto i valori INI_ALL: si possono modificare da qualsiasi script. I valori INI_PERDIR non si possono modificare con ini_set(), ma sì tramite un .htaccess con mod_php o un .user.ini con PHP-FPM. Chi ha permessi di scrittura nel webroot, quindi anche codice iniettato, può creare tali file.
php_admin_value nel pool FPM e in Apache
Con PHP-FPM i valori stanno nel file del pool. Il manuale PHP stabilisce: i valori impostati con php_admin_value e php_admin_flag non si possono sovrascrivere con ini_set(). Per i valori on/off usi php_admin_flag, per tutti gli altri php_admin_value.
; /etc/php/8.3/fpm/pool.d/seite1.conf (estratto)
[seite1]
user = seite1
group = seite1
listen = /run/php/seite1.sock
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/seite1-fehler.log
php_admin_value[open_basedir] = /var/www/seite1/:/tmp/seite1/
Secondo php.net memory_limit=-1 va nella configurazione solo insieme a un limite di memoria tramite container o cgroup. Come ci si riesce con systemd lo spiega l'articolo Impostare limiti di memoria con systemd e cgroup.
Con Apache e mod_php le direttive vanno nella configurazione del server o nel VirtualHost. Secondo il manuale PHP non sono consentite in .htaccess e, una volta impostate, né .htaccess né ini_set() possono modificarle.
<VirtualHost *:443>
ServerName www.example.de
DocumentRoot /var/www/seite1/public
<IfModule php_module>
php_admin_value memory_limit -1
php_admin_value post_max_size 32M
php_admin_value upload_max_filesize 24M
php_admin_flag session.upload_progress.enabled off
php_admin_flag display_errors off
</IfModule>
</VirtualHost>
Due finezze dal manuale: per cancellare un valore impostato in precedenza, usi none come valore. E le costanti PHP come E_ALL non hanno significato nella configurazione di Apache; per error_reporting deve indicare lì il valore numerico.
Quali valori bloccare
Non ogni impostazione deve essere bloccata. Ha senso per tutto ciò che riguarda la sicurezza o serve come misura transitoria:
- I valori transitori di PHP2Shell di php.net:
memory_limit,post_max_size,upload_max_filesize,session.upload_progress.enablede, su PHP 8.5,fatal_error_backtraces. - Output degli errori e registrazione:
display_errors,display_startup_errors,log_errors,error_log. - Accesso ai file e isolamento:
open_basedir,upload_tmp_dir,session.save_path. - Accessi di rete da PHP:
allow_url_includee, se l'applicazione non ne ha bisogno,allow_url_fopen. - Funzioni bloccate tramite
disable_functions, che nel pool, secondo il manuale, integrano l'elenco di php.ini e non lo sostituiscono. Dettagli nella guida Usare correttamente disable_functions.
Per session.upload_progress.enabled il blocco è particolarmente importante, perché altrimenti il valore potrebbe essere riattivato tramite un .user.ini. Maggiori informazioni in Disattivare session.upload_progress: nel modo giusto e per sempre.
Verificare che il blocco funzioni
Dopo ogni modifica riavvii il servizio e verifichi il valore nel contesto web. Un breve file di prova, subito cancellato di nuovo, mostra se il pool mantiene il valore anche quando l'applicazione vuole modificarlo:
<?php
// File di prova: collocarlo per poco, richiamarlo una volta tramite il dominio, cancellarlo subito
header('Content-Type: text/plain');
$vorher = ini_get('memory_limit');
$versuch = @ini_set('memory_limit', '256M');
echo "memory_limit: $vorher\n";
echo 'Änderung per ini_set() ', ($versuch === false ? 'blockiert' : 'MÖGLICH'), "\n";
Ci si aspetta -1 e blockiert. Se l'output è MÖGLICH, il valore non è impostato tramite php_admin_value oppure il servizio non è ancora stato riavviato. Ripeta la verifica per ogni pool e ogni versione di PHP.
Registri i valori bloccati in modo centralizzato, ad esempio in un modello di pool o nella Sua gestione della configurazione. I pannelli di hosting talvolta sovrascrivono i file di pool modificati a mano al salvataggio successivo; lì i valori vanno nei campi previsti dal pannello.
Come PHP ordina nel complesso i propri livelli di configurazione lo spiega Il php.ini spiegato: struttura, livelli e precedenza. Le misure transitorie complete sono in Misure immediate se non può ancora applicare la patch.
Conclusione: solo ciò che è bloccato è davvero impostato
Le misure transitorie di php.net per PHP2Shell hanno portato all'attenzione una distinzione che prima veniva spesso trascurata: un valore in php.ini è, per molte impostazioni, solo un suggerimento, un valore in php_admin_value una prescrizione. Per valori di comodità come il fuso orario la differenza è irrilevante. Per le impostazioni di sicurezza e le misure transitorie decide se la misura agisca davvero nell'esercizio.
Lo sforzo è contenuto: una manciata di righe per pool o VirtualHost, un riavvio, una breve verifica. Tenga piccolo e motivato l'elenco dei valori bloccati, in modo che gli sviluppatori capiscano perché la loro applicazione non può modificare un valore. E curi l'elenco nei Suoi modelli, in modo che i nuovi siti lo ereditino automaticamente.
Come aiuta PHP SOS in concreto?
- Leggere i livelli: stabiliamo per ogni sito quali valori di php.ini, pool, Apache,
.htaccesso.user.inivalgano effettivamente. - Impostare i blocchi: inseriamo i valori rilevanti per la sicurezza e le misure transitorie per PHP2Shell come
php_admin_valueophp_admin_flage riavviamo i servizi. - Testare l'applicazione: verifichiamo che l'applicazione giri senza errori con i valori bloccati e analizziamo il log degli errori.
- Curare i modelli: nell'ambito dell'hardening del server riportiamo i valori in modelli di pool e documentazione.
Domande frequenti
Qual è la differenza tra php_value e php_admin_value?
Entrambi impostano un'impostazione PHP. I valori di php_value l'applicazione può poi modificarli di nuovo, ad esempio con ini_set() o .htaccess. I valori di php_admin_value e php_admin_flag, secondo il manuale PHP, sono bloccati per ini_set(), con Apache anche per .htaccess.
Posso scrivere php_admin_value in un file .htaccess?
No. Secondo il manuale PHP, php_admin_value non è consentito nei file .htaccess. Va nella configurazione del server Apache o nel VirtualHost, con PHP-FPM nel file del pool.
Che cosa succede se un'applicazione vuole modificare un valore bloccato?
La chiamata a ini_set() fallisce e restituisce false, il valore bloccato resta. Le applicazioni programmate bene se la cavano. Dopo il passaggio verifichi comunque il log degli errori e le funzioni principali.
Devo riavviare dopo una modifica nel pool?
Sì. PHP-FPM legge i file dei pool all'avvio o al ricaricamento del servizio. Con Apache e mod_php vale lo stesso per la configurazione del server. Senza riavvio continua a valere il vecchio valore.
disable_functions si può estendere nel pool?
Sì, con una particolarità: secondo il manuale PHP, disable_functions nel pool FPM non sovrascrive i valori di php.ini, ma li integra. Il pool può quindi bloccare altre funzioni, ma non liberarne nessuna.