Aktuální situace: PHP2Shell. Dvě kritické zranitelnosti PHP (CVSS 9.2) umožňují spustit škodlivý kód bez přihlášení. Záplaty od 21. 10. 2026.Co nyní udělat →

php_admin_value: uzamknutí nastavení proti přepsání

Bezpečnostní nastavení málo platí, když ho aplikace jedním řádkem kódu změní zpět. Pomocí php_admin_value a php_admin_flag určíte hodnoty pro PHP-FPM a Apache závazně.

Stav 5 min čteníHardening a konfigurace

Stručně: php_admin_value a php_admin_flag nastavují hodnoty PHP v poolu PHP-FPM nebo v konfiguraci Apache tak, aby je aplikace nemohly změnit ani pomocí ini_set(), ani pomocí .htaccess. Přesně to php.net pro přechodná opatření k PHP2Shell požaduje, například u memory_limit=-1. Po nastavení se musí služba restartovat a hodnota by se měla ověřit z webu.

Proč „nastaveno“ neznamená „uzamčeno“

Ve dnech po 21. říjnu 2026 zapsalo mnoho správců přechodná opatření od php.net do svého php.ini. Jeden detail doporučení přitom často zapadl: memory_limit=-1 má být nastaveno tak, aby ho aplikace nemohly přepsat. php.net k tomu výslovně uvádí php_admin_value v poolu FPM nebo v konfiguraci Apache.

Důvod je prostý. Mnoho CMS, e-shopů a frameworků nastavuje své vlastní hodnoty, například vyšší limit paměti pro importy. Pokud je hodnota jen v php.ini, aplikace ji při dalším volání přepíše. Ochranné opatření pak existuje na papíře, ne v běžícím procesu.

Netýká se to jen PHP2Shell. Každé zpevnění, od vypnutých chybových výstupů po limity nahrávání, je jen tak silné jako jeho nejslabší úroveň.

Kdo smí nastavení PHP vůbec měnit

PHP zná čtyři režimy změny. Každé nastavení má jeden z nich a určuje, na kterých místech lze nastavit. Významy pocházejí z příručky PHP.

Režim Kde lze hodnotu nastavit Příklady
INI_USER ve skriptu pomocí ini_set() a v .user.ini několik hodnot za běhu
INI_PERDIR php.ini, .htaccess, httpd.conf, .user.ini post_max_size, session.upload_progress.enabled
INI_SYSTEM jen php.ini nebo httpd.conf file_uploads, disable_functions
INI_ALL všude, i pomocí ini_set() memory_limit, display_errors, open_basedir

Nebezpečné jsou především hodnoty INI_ALL: lze je změnit z libovolného skriptu. Hodnoty INI_PERDIR sice nelze měnit pomocí ini_set(), ale přes .htaccess u mod_php nebo .user.ini u PHP-FPM ano. Kdo má právo zápisu do webrootu, tedy i vložený kód, může takové soubory vytvořit.

php_admin_value v poolu FPM a v Apache

U PHP-FPM jsou hodnoty v souboru poolu. Příručka PHP uvádí: hodnoty nastavené pomocí php_admin_value a php_admin_flag nelze přepsat pomocí ini_set(). Pro hodnoty zapnuto-vypnuto použijte php_admin_flag, pro všechny ostatní php_admin_value.

; /etc/php/8.3/fpm/pool.d/seite1.conf (výňatek)
[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 patří podle php.net do konfigurace jen společně s limitem paměti přes kontejner nebo cgroup. Jak to zvládnout pomocí systemd, je v článku Nastavení limitů paměti pomocí systemd a cgroups.

U Apache s mod_php patří direktivy do konfigurace serveru nebo do VirtualHost. Podle příručky PHP nejsou v .htaccess povoleny a po nastavení je nemůže změnit ani .htaccess, ani ini_set().

<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>

Dvě jemnosti z příručky: Chcete-li dříve nastavenou hodnotu smazat, použijte jako hodnotu none. A konstanty PHP jako E_ALL nemají v konfiguraci Apache žádný význam; pro error_reporting tam musíte zadat číselnou hodnotu.

Které hodnoty uzamknout

Ne každé nastavení musí být uzamčeno. Smysl to má u všeho, co se týká bezpečnosti nebo slouží jako přechodné opatření:

  1. Přechodné hodnoty php.net k PHP2Shell: memory_limit, post_max_size, upload_max_filesize, session.upload_progress.enabled a u PHP 8.5 fatal_error_backtraces.
  2. Chybový výstup a protokolování: display_errors, display_startup_errors, log_errors, error_log.
  3. Přístup k souborům a izolace: open_basedir, upload_tmp_dir, session.save_path.
  4. Síťové přístupy z PHP: allow_url_include a, pokud ji aplikace nepotřebuje, allow_url_fopen.
  5. Zakázané funkce přes disable_functions, které v poolu podle příručky doplňují seznam z php.ini, nenahrazují ho. Podrobnosti v průvodci Správné použití disable_functions.

U session.upload_progress.enabled je uzamčení zvlášť důležité, protože by hodnotu jinak šlo přes .user.ini znovu zapnout. Více v článku Vypnutí session.upload_progress: správně a trvale.

Ověřit, že uzamčení platí

Po každé změně službu restartujte a hodnotu ověřte z webu. Krátký, ihned smazaný kontrolní soubor ukáže, zda pool hodnotu drží, i když ji aplikace chce změnit:

<?php
// Kontrolní soubor: krátce umístit, jednou zavolat přes doménu, ihned smazat
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";

Očekává se -1 a „blockiert“. Pokud je výstup „MÖGLICH“, hodnota není nastavena přes php_admin_value nebo služba ještě nebyla restartována. Kontrolu zopakujte pro každý pool a každou verzi PHP.

Tip

Uzamčené hodnoty vedete centrálně, například v šabloně poolu nebo ve své správě konfigurace. Hostingové panely někdy ručně upravené soubory poolů při dalším uložení přepíší; tam patří hodnoty do polí, která panel předvídá.

Jak PHP své úrovně konfigurace celkově řadí, vysvětluje php.ini vysvětleno: struktura, úrovně a přednost. Úplná přechodná opatření jsou na stránce Okamžitá opatření, když zatím nemůžete záplatovat.

Závěr: teprve uzamčeno je skutečně nastaveno

Přechodná opatření php.net k PHP2Shell přivedla do povědomí rozdíl, který se dříve často přehlížel: hodnota v php.ini je u mnoha nastavení jen návrh, hodnota v php_admin_value je předpis. U pohodlných hodnot, jako je časové pásmo, je rozdíl nepodstatný. U bezpečnostních nastavení a přechodných opatření rozhoduje o tom, zda opatření v běžícím provozu vůbec zabírá.

Pracnost je přehledná: hrstka řádků na pool nebo VirtualHost, restart, krátká kontrola. Udržujte seznam uzamčených hodnot krátký a odůvodněný, aby vývojáři chápali, proč jejich aplikace nesmí hodnotu změnit. A seznam udržujte ve svých šablonách, aby ho nové weby dědily automaticky.

Jak konkrétně pomáhá PHP SOS?

  • Načíst úrovně: Pro každý web zjistíme, které hodnoty z php.ini, poolu, Apache, .htaccess nebo .user.ini skutečně platí.
  • Nastavit uzamčení: Bezpečnostně relevantní hodnoty a přechodná opatření k PHP2Shell zapíšeme jako php_admin_value popř. php_admin_flag a restartujeme služby.
  • Otestovat aplikaci: Ověříme, zda aplikace s uzamčenými hodnotami běží bez chyb, a vyhodnotíme chybový log.
  • Udržovat šablony: V rámci zpevnění serveru převezmeme hodnoty do šablon poolů a dokumentace.

Časté dotazy

Jaký je rozdíl mezi php_value a php_admin_value?

Obojí nastaví hodnotu PHP. Hodnoty z php_value může aplikace později změnit, například pomocí ini_set() nebo .htaccess. Hodnoty z php_admin_value a php_admin_flag jsou podle příručky PHP uzamčeny pro ini_set(), u Apache i pro .htaccess.

Mohu php_admin_value zapsat do souboru .htaccess?

Ne. Podle příručky PHP není php_admin_value v souborech .htaccess povoleno. Patří do konfigurace serveru Apache nebo do VirtualHost, u PHP-FPM do souboru poolu.

Co se stane, když chce aplikace změnit uzamčenou hodnotu?

Volání ini_set() selže a vrátí false, uzamčená hodnota zůstane. Dobře naprogramované aplikace si s tím poradí. Po přechodu přesto zkontrolujte chybový log a nejdůležitější funkce.

Musím po změně v poolu restartovat?

Ano. PHP-FPM čte soubory poolů při startu nebo při opětovném načtení služby. U Apache s mod_php platí totéž pro konfiguraci serveru. Bez restartu běží stará hodnota dál.

Lze disable_functions v poolu rozšířit?

Ano, s jednou zvláštností: podle příručky PHP disable_functions v poolu FPM hodnoty z php.ini nepřepisuje, ale doplňuje. Pool tedy může zakázat další funkce, ale žádnou povolit.

Zdroje

Okamžitý kontakt

Každá hodina se počítá. Napište nám hned.

Stručně popište systém, verzi PHP a pozorování. Ozveme se, vyjasníme situaci a budeme pracovat na dálku, dokud nebude incident uzavřen a zdokumentován.

Okamžitá pomoc