Pe scurt: php_admin_value și php_admin_flag stabilesc setările PHP în pool-ul PHP-FPM sau în configurația Apache astfel încât aplicațiile să nu le poată modifica nici prin ini_set(), nici prin .htaccess. php.net cere exact acest lucru pentru măsurile provizorii PHP2Shell, de exemplu pentru memory_limit=-1. După stabilire, serviciul trebuie repornit, iar valoarea ar trebui verificată în contextul web.
De ce „stabilit” nu înseamnă „blocat”
În zilele de după 21 octombrie 2026, mulți administratori au scris măsurile provizorii de la php.net în php.ini. Un detaliu al recomandării a trecut adesea neobservat: memory_limit=-1 trebuie stabilit astfel încât aplicațiile să nu îl poată suprascrie. php.net indică în acest scop explicit php_admin_value în pool-ul FPM sau în configurația Apache.
Motivul este simplu. Multe CMS-uri, magazine și framework-uri își stabilesc propriile valori, de exemplu o limită de memorie mai mare pentru importuri. Dacă valoarea se află doar în php.ini, aplicația o suprascrie la următoarea apelare. Măsura de protecție există atunci pe hârtie, dar nu în procesul în execuție.
Asta nu privește doar PHP2Shell. Orice securizare, de la ieșirile de erori dezactivate la limitele de upload, este tot atât de puternică cât cel mai slab nivel al ei.
Cine are voie să modifice setările PHP
PHP cunoaște patru moduri de modificare. Fiecare setare are unul dintre ele, iar acesta stabilește în ce locuri poate fi setată. Semnificațiile provin din manualul PHP.
| Mod | Unde poate fi stabilită valoarea | Exemple |
|---|---|---|
INI_USER |
în script prin ini_set() și în .user.ini |
puține valori de execuție |
INI_PERDIR |
php.ini, .htaccess, httpd.conf, .user.ini |
post_max_size, session.upload_progress.enabled |
INI_SYSTEM |
doar php.ini sau httpd.conf |
file_uploads, disable_functions |
INI_ALL |
peste tot, inclusiv prin ini_set() |
memory_limit, display_errors, open_basedir |
Periculoase sunt mai ales valorile INI_ALL: ele pot fi modificate din orice script. Valorile INI_PERDIR nu pot fi modificate prin ini_set(), dar pot fi modificate printr-un .htaccess la mod_php sau printr-un .user.ini la PHP-FPM. Cine are drepturi de scriere în webroot, deci și codul introdus, poate crea astfel de fișiere.
php_admin_value în pool-ul FPM și în Apache
La PHP-FPM, valorile se află în fișierul pool-ului. Manualul PHP precizează: valorile stabilite cu php_admin_value și php_admin_flag nu pot fi suprascrise prin ini_set(). Pentru valorile de tip pornit-oprit folosiți php_admin_flag, pentru toate celelalte php_admin_value.
; /etc/php/8.3/fpm/pool.d/seite1.conf (extras)
[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/
memory_limit=-1 aparține, potrivit php.net, în configurație doar împreună cu o limită de memorie prin container sau cgroup. Cum reușiți acest lucru cu systemd se găsește în articolul Stabilirea limitelor de memorie cu systemd și cgroups.
La Apache cu mod_php, directivele aparțin configurației serverului sau VirtualHost-ului. Potrivit manualului PHP, ele nu sunt permise în .htaccess, iar odată stabilite, nici .htaccess, nici ini_set() nu le pot modifica.
<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>
Două subtilități din manual: pentru a șterge o valoare stabilită anterior, folosiți none ca valoare. Iar constantele PHP precum E_ALL nu au nicio semnificație în configurația Apache; pentru error_reporting trebuie să indicați acolo valoarea numerică.
Ce valori ar trebui să blocați
Nu orice setare trebuie blocată. Are sens pentru tot ce ține de securitate sau servește drept măsură provizorie:
- Valorile provizorii PHP2Shell de la php.net:
memory_limit,post_max_size,upload_max_filesize,session.upload_progress.enabledși, la PHP 8.5,fatal_error_backtraces. - Ieșirea erorilor și jurnalizarea:
display_errors,display_startup_errors,log_errors,error_log. - Accesul la fișiere și izolarea:
open_basedir,upload_tmp_dir,session.save_path. - Accesările de rețea din PHP:
allow_url_includeși, dacă aplicația nu are nevoie,allow_url_fopen. - Funcțiile blocate prin
disable_functions, care în pool, potrivit manualului, completează lista din php.ini și nu o înlocuiesc. Detalii în ghidul Folosirea corectă a disable_functions.
La session.upload_progress.enabled, blocarea este deosebit de importantă, deoarece altfel valoarea ar putea fi reactivată printr-un .user.ini. Mai multe la session.upload_progress dezactivat: corect și durabil.
Verificați dacă blocarea funcționează
După fiecare modificare reporniți serviciul și verificați valoarea în contextul web. Un fișier de verificare scurt, șters imediat după aceea, arată dacă pool-ul își păstrează valoarea chiar dacă aplicația vrea să o modifice:
<?php
// Fișier de verificare: depuneți-l pe scurt, apelați-l o dată prin domeniu, ștergeți-l imediat
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";
Se așteaptă -1 și textul „blockiert” în ieșirea fișierului de verificare. Dacă ieșirea arată „MÖGLICH”, valoarea nu este stabilită prin php_admin_value sau serviciul nu a fost încă repornit. Repetați verificarea pentru fiecare pool și fiecare versiune PHP.
Consemnați central valorile blocate, de exemplu într-un șablon de pool sau în gestiunea configurației. Panourile de hosting suprascriu uneori fișierele de pool modificate manual la următoarea salvare; acolo valorile aparțin câmpurilor prevăzute de panou.
Cum își ordonează PHP, în ansamblu, nivelurile de configurare explică php.ini explicat: structură, niveluri și prioritate. Măsurile provizorii complete se găsesc la Măsuri imediate dacă nu puteți încă aplica patchul.
Concluzie: abia blocat este cu adevărat stabilit
Măsurile provizorii de la php.net pentru PHP2Shell au adus în atenție o distincție care înainte era adesea trecută cu vederea: o valoare din php.ini este, pentru multe setări, doar o sugestie, iar o valoare din php_admin_value este o prescripție. Pentru valori de confort, precum fusul orar, diferența este nesemnificativă. Pentru setările de securitate și măsurile provizorii, ea decide dacă măsura se aplică deloc în funcționarea reală.
Efortul este rezonabil: o mână de rânduri pentru fiecare pool sau VirtualHost, o repornire, o scurtă verificare. Păstrați lista valorilor blocate scurtă și motivată, pentru ca dezvoltatorii să poată înțelege de ce aplicația lor nu are voie să modifice o valoare. Și întrețineți lista în șabloanele dumneavoastră, pentru ca site-urile noi să o moștenească automat.
Cum ajută PHP SOS concret?
- Citirea nivelurilor: Stabilim pentru fiecare site ce valori din php.ini, pool, Apache,
.htaccesssau.user.inise aplică efectiv. - Stabilirea blocărilor: Introducem valorile relevante pentru securitate și măsurile provizorii PHP2Shell ca
php_admin_valuerespectivphp_admin_flagși repornim serviciile. - Testarea aplicației: Verificăm dacă aplicația rulează fără erori cu valorile blocate și evaluăm jurnalul de erori.
- Întreținerea șabloanelor: În cadrul securizării serverului preluăm valorile în șabloanele de pool și în documentație.
Întrebări frecvente
Care este diferența dintre php_value și php_admin_value?
Amândouă stabilesc o setare PHP. Valorile din php_value pot fi modificate ulterior de aplicație, de exemplu prin ini_set() sau .htaccess. Valorile din php_admin_value și php_admin_flag sunt, potrivit manualului PHP, blocate pentru ini_set(), iar la Apache și pentru .htaccess.
Pot scrie php_admin_value într-un fișier .htaccess?
Nu. Potrivit manualului PHP, php_admin_value nu este permis în fișierele .htaccess. Aparține configurației serverului Apache sau VirtualHost-ului, iar la PHP-FPM fișierului pool-ului.
Ce se întâmplă dacă o aplicație vrea să modifice o valoare blocată?
Apelul ini_set() eșuează și returnează false, iar valoarea blocată rămâne. Aplicațiile bine programate se descurcă cu asta. După trecere, verificați totuși jurnalul de erori și funcțiile cele mai importante.
Trebuie să repornesc după o modificare în pool?
Da. PHP-FPM citește fișierele pool-ului la pornirea sau la reîncărcarea serviciului. La Apache cu mod_php se aplică același lucru pentru configurația serverului. Fără repornire continuă să ruleze valoarea veche.
Poate fi extins disable_functions în pool?
Da, cu o particularitate: potrivit manualului PHP, disable_functions din pool-ul FPM nu suprascrie valorile din php.ini, ci le completează. Pool-ul poate deci bloca funcții suplimentare, dar nu poate elibera niciuna.