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 →

display_errors off: vypnutí chybových výstupů v produkci

Viditelná chybová hlášení PHP prozrazují cesty, názvy databází a verze. Jak je vypnout v PHP, ve frameworku i ve webovém serveru a přitom nepustit chyby z očí.

Stav 5 min čteníHardening a konfigurace

Stručně: Na ostrém webu patří display_errors = Off do php.ini, spolu s display_startup_errors = Off, log_errors = On a chybovým logem mimo webroot. CMS a frameworky navíc musí běžet v produkčním režimu, jinak podrobnosti ukazují jejich vlastní chybové stránky. Uzamčeno pomocí php_admin_flag a po každé aktualizaci ověřeno, zůstávají chyby v logu místo v prohlížeči.

Co prozradí jediné chybové hlášení

Varování v horním okraji stránky, „Fatal error“ místo přehledu objednávky: takové výstupy vypadají neškodně. Pro útočníka jsou mapou. Ukazují úplné cesty k souborům, názvy databází a tabulek, použité knihovny a často i verzi PHP.

Právě v situacích jako PHP2Shell, kdy se masivně hledají zranitelné servery, by server měl o sobě prozrazovat co nejméně. Žádnou mezeru v interpretu PHP to neuzavře, ale ztíží to každý další krok po průniku a cílené útoky na vaši aplikaci to činí namáhavějšími.

K tomu přistupuje ochrana osobních údajů. Chybová hlášení mohou obsahovat části požadavků, například e-mailové adresy z formulářů. Co se objeví v prohlížeči návštěvníka, už nemáte pod kontrolou.

Výchozí hodnoty nejsou určeny pro produkci

Mnozí předpokládají, že PHP chyby samo skrývá. Příručka PHP říká něco jiného: vestavěná výchozí hodnota display_errors je 1 a display_startup_errors je od PHP 8.0 rovněž standardně zapnuto. Teprve dodávaná šablona php.ini-production obojí nastavuje na Off. Příručka označuje display_errors výslovně za vývojovou funkci, která by se na systémech v internetu nikdy neměla používat.

Zda váš server používá produkční šablonu, není samozřejmé. Image kontejnerů někdy startují zcela bez php.ini, hostingové panely nastavují vlastní hodnoty a po přestěhování se rádo zkopíruje vývojová šablona.

display_errors off: přehled nastavení

Následující hodnoty jsou pro produkční servery rozumné. Konstanty jako E_ALL fungují jen v php.ini; v konfiguraci Apache nemají podle příručky PHP význam a je nutné je zadat jako číslo.

Nastavení Produkce Účel
display_errors Off žádné chyby v prohlížeči
display_startup_errors Off žádné chyby při startu PHP ve výstupu
log_errors On zapisovat chyby do protokolu
error_log cesta mimo webroot vlastní logovací soubor pro každý web nebo pool
error_reporting E_ALL protokolovat všechny chyby, nezobrazovat
html_errors Off prostý text místo HTML v protokolech
zend.exception_ignore_args On žádné argumenty funkcí ve stack trace
fatal_error_backtraces 0 do aktualizace (jen PHP 8.5) přechodné opatření podle php.net

zend.exception_ignore_args je zvlášť cenné. Bez tohoto nastavení mohou stack trace v lozích a na chybových stránkách obsahovat argumenty volání funkcí, tedy i hesla nebo tokeny, které se právě zpracovávaly.

; php.ini webového SAPI
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/website-fehler.log
error_reporting = E_ALL
html_errors = Off
zend.exception_ignore_args = On
; jen PHP 8.5, přechodné opatření do aktualizace na 8.5.12:
; fatal_error_backtraces = 0

V poolu FPM nejdůležitější hodnoty navíc uzamkněte, aby je žádná aplikace pomocí ini_set() nezapnula zpět:

; např. /etc/php/8.3/fpm/pool.d/seite1.conf
php_admin_flag[display_errors] = off
php_admin_flag[display_startup_errors] = off
php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php/seite1-fehler.log

Poté restartujte příslušnou službu PHP. Jak přesně uzamykání funguje, vysvětluje článek php_admin_value: uzamknutí nastavení proti přepsání. Úplnou základní konfiguraci najdete v článku Bezpečná konfigurace php.ini.

Druhý přepínač: ladicí režim aplikace

PHP je jen polovina práce. Moderní frameworky chyby zachytávají samy a zobrazují vlastní, často velmi podrobné chybové stránky. V ladicím režimu obsahují výňatky ze zdrojového kódu, hodnoty konfigurace a někdy i proměnné prostředí. Tyto stránky se zobrazí i tehdy, když je display_errors v PHP vypnuto.

Zkontrolujte proto u každé aplikace její vlastní přepínač. U WordPressu jsou to WP_DEBUG a WP_DEBUG_DISPLAY v wp-config.php, u Laravelu a Symfony APP_DEBUG a prostředí v souboru .env, u jiných systémů produkční režim podle dokumentace výrobce. Na ostrém systému patří ladicí režim trvale vypnout, i „jen na chvíli k testování“ je riziko.

Jak se s chybami v aplikaci zachází čistě, místo aby se potlačovaly, popisuje Chyby a výjimky v PHP.

Jak najít chybové výstupy dříve než ostatní

Jednorázové nastavení nestačí. Chybové výstupy se po aktualizacích, stěhováních nebo změnách v panelu vracejí. Pomůže krátký kontrolní postup:

  1. Zkontrolovat platné hodnoty z webu, nejen z příkazové řádky, například krátce umístěným a ihned smazaným kontrolním souborem.
  2. Zkontrolovat ladicí režim každé aplikace v jejím konfiguračním souboru.
  3. Prohledat doručené stránky na typické texty chyb, jak ukazuje blok kódu níže.
  4. Ve vyhledávači pomocí dotazu site: na vaši doménu hledat výrazy jako „Fatal error“ nebo „Warning“.
  5. Ověřit, že se do chybového logu zapisuje a že neleží ve webrootu.
# Prohledat doručené stránky na texty chyb PHP (jen vlastní domény)
for url in https://www.example.de/ https://www.example.de/kontakt/; do
  curl -s "$url" | grep -E -o "(Fatal error|Warning|Notice|Deprecated|Stack trace)[^<]{0,80}" | head -3
done
# Zapisuje se do chybového logu?
ls -l /var/log/php/
Důležité

Skrývat chyby není náhradou za jejich odstranění. Log plný varování je upozornění na potřebu údržby a po průniku je často důležitou stopou. Co při tom protokolovat a co ne, popisuje Bezpečné logování: protokolovat chyby bez úniku dat.

Závěr: tiše v prohlížeči, hovorně v logu

Pravidlo pro produkční servery je jednoduché: chyby patří do protokolu, ne na web. V praxi selhává na výchozích hodnotách, které nejsou určeny pro produkci, na ladicích přepínačích v aplikacích a na konfiguracích, které se po aktualizacích nebo stěhováních vrátí zpět.

Kdo vypne display_errors a display_startup_errors, uzamkne hodnoty v poolu, zkontroluje ladicí režim aplikace a výsledek pravidelně ověřuje, uzavře jeden z nejčastějších zdrojů zbytečného úniku informací. Pracnost je nízká, účinek vydrží, dokud kontrola zůstává součástí každé aktualizace.

Jeden bod by neměl zapadnout: chybový log není odpadkový koš. Kdo jej pravidelně čte, pozná chybné aktualizace, zastaralé funkce a někdy i první stopy útoku, dlouho před tím, než si zákazníci něčeho všimnou.

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

  • Zkontrolovat: Načteme platná nastavení chyb pro každý web a pool a doručené stránky prohledáme na chybové výstupy.
  • Přepnout: Nastavení PHP a aplikací nastavíme pro ostrý provoz a uzamkneme je proti přepsání.
  • Zřídit protokoly: Chybové logy leží mimo webroot, rotují se a jsou přístupné vašim vývojářům.
  • Udržet trvale: V rámci smlouvy o bezpečnostní údržbě nastavení po každé aktualizaci znovu zkontrolujeme.

Časté dotazy

Není display_errors v PHP stejně vypnuto?

Ne automaticky. Podle příručky PHP je vestavěná výchozí hodnota display_errors 1. Teprve dodávaná šablona php.ini-production nastavuje Off. Zda váš server tuto šablonu používá, závisí na distribuci, panelu nebo image kontejneru a je třeba to ověřit.

Stačí display_errors = Off, když WordPress nebo Laravel běží v ladicím režimu?

Ne. Mnoho CMS a frameworků má vlastní chybové stránky, které mohou zobrazovat podrobnosti nezávisle na PHP. Vypněte proto i ladicí režim aplikace, například WP_DEBUG_DISPLAY u WordPressu nebo APP_DEBUG u Laravelu a Symfony.

Kam jdou chyby, když se už nezobrazují?

S log_errors = On je PHP zapisuje do souboru, který určuje error_log, nebo do protokolu příslušného provozního režimu, například do chybového logu Apache nebo PHP-FPM. Soubor by měl ležet mimo webroot a pravidelně se rotovat.

Co má fatal_error_backtraces společného s PHP2Shell?

Nastavení existuje od PHP 8.5 a je standardně aktivní. php.net uvádí fatal_error_backtraces=0 s následným restartem jako jedno z přechodných opatření pro PHP 8.5, dokud aktualizace na 8.5.12 chybí. Aktualizaci nenahrazuje.

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