Trenutno stanje: PHP2Shell. Dvije kritične PHP ranjivosti (CVSS 9.2) omogućuju zlonamjerni kod bez prijave. Zakrpe od 21. 10. 2026.Što sada učiniti →

display_errors off: isključiti ispis pogrešaka u produkciji

Vidljive PHP poruke o pogreškama odaju putove, nazive baza podataka i verzije. Evo kako ih isključiti u PHP-u, frameworku i web-poslužitelju, a pogreške ne ispustiti iz vida.

Stanje 5 min čitanjaOjačavanje i konfiguracija

Ukratko: Na živoj web-stranici display_errors = Off pripada u php.ini, zajedno s display_startup_errors = Off, log_errors = On i zapisnikom pogrešaka izvan web-korijena. Uz to CMS-ovi i frameworki moraju raditi u produkcijskom načinu, inače njihove vlastite stranice s pogreškama prikazuju pojedinosti. Zaključane pomoću php_admin_flag i provjeravane nakon svakog ažuriranja, pogreške ostaju u zapisniku umjesto u pregledniku.

Što odaje jedna jedina poruka o pogrešci

Upozorenje na vrhu stranice, „Fatal error“ umjesto pregleda narudžbe: takvi ispisi izgledaju bezazleno. Za napadača su karta. Pokazuju potpune putove datoteka, nazive baza podataka i tablica, korištene biblioteke i često verziju PHP-a.

Osobito u situacijama poput PHP2Shella, u kojima se masovno traže ranjivi poslužitelji, poslužitelj bi trebao odavati što je moguće manje o sebi. To ne zatvara ranjivost u PHP interpreteru, ali otežava svaki daljnji korak nakon provale i čini ciljane napade na Vašu aplikaciju mukotrpnijima.

Tu je i zaštita podataka. Poruke o pogreškama mogu sadržavati dijelove zahtjeva, primjerice e-adrese iz obrazaca. Što se pojavi u pregledniku posjetitelja, više nije pod Vašom kontrolom.

Zadane vrijednosti nisu zamišljene za produkciju

Mnogi pretpostavljaju da PHP pogreške sam skriva. PHP priručnik kaže drugo: ugrađena zadana vrijednost display_errors je 1, a display_startup_errors je od PHP-a 8.0 također zadano uključen. Tek isporučeni predložak php.ini-production postavlja oboje na Off. Priručnik display_errors izričito naziva razvojnom funkcijom koju nikada ne treba koristiti na sustavima na internetu.

Koristi li Vaš poslužitelj produkcijski predložak, nije samorazumljivo. Image-i kontejnera katkad se pokreću posve bez php.ini, hosting paneli postavljaju vlastite vrijednosti, a nakon selidbe rado se kopira razvojni predložak.

display_errors off: pregled postavki

Sljedeće vrijednosti smislene su za produkcijske poslužitelje. Konstante poput E_ALL rade samo u php.ini; u Apache konfiguraciji prema PHP priručniku nemaju značenje i moraju se navesti kao broj.

Postavka Produkcija Svrha
display_errors Off nema pogrešaka u pregledniku
display_startup_errors Off nema pogrešaka pri pokretanju PHP-a u izlazu
log_errors On pogreške upisivati u zapisnik
error_log putanja izvan web-korijena zasebna zapisnička datoteka po web-stranici ili poolu
error_reporting E_ALL zapisivati sve pogreške, ne prikazivati
html_errors Off običan tekst umjesto HTML-a u zapisnicima
zend.exception_ignore_args On bez argumenata funkcija u stack traceovima
fatal_error_backtraces 0 do ažuriranja (samo PHP 8.5) prijelazna mjera prema php.net-u

zend.exception_ignore_args osobito je vrijedan. Bez te postavke stack traceovi u zapisnicima i na stranicama s pogreškama mogu sadržavati argumente poziva funkcija, dakle i lozinke ili tokene koji su upravo obrađivani.

; php.ini web SAPI-ja
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
; samo PHP 8.5, prijelazna mjera do ažuriranja na 8.5.12:
; fatal_error_backtraces = 0

U FPM poolu najvažnije vrijednosti dodatno zaključajte kako ih nijedna aplikacija ne bi putem ini_set() ponovno uključila:

; npr. /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

Zatim ponovno pokrenite dotičnu PHP uslugu. Kako zaključavanje točno funkcionira, objašnjava članak php_admin_value: zaključati postavke od nadjačavanja. Potpunu osnovnu konfiguraciju naći ćete u članku Sigurno konfigurirati php.ini.

Druga sklopka: debug način aplikacije

PHP je tek pola posla. Moderni frameworki sami hvataju pogreške i prikazuju vlastite, često vrlo opširne stranice s pogreškama. U debug načinu sadrže izvatke izvornog koda, konfiguracijske vrijednosti i ponekad varijable okruženja. Te se stranice pojavljuju čak i kad je display_errors u PHP-u isključen.

Zato za svaku aplikaciju provjerite njezinu vlastitu sklopku. Kod WordPressa to su WP_DEBUG i WP_DEBUG_DISPLAY u wp-config.php, kod Laravela i Symfonyja APP_DEBUG i okruženje u datoteci .env, kod drugih sustava produkcijski način prema dokumentaciji proizvođača. Na živom sustavu debug način trajno pripada isključen, a i „samo načas za testiranje“ je rizik.

Kako se pogreške u aplikaciji uredno obrađuju umjesto da se potiskuju, opisuje članak Pogreške i iznimke u PHP-u.

Kako pronaći ispise pogrešaka prije nego ih nađu drugi

Jednokratno postavljanje nije dovoljno. Ispisi pogrešaka vraćaju se nakon ažuriranja, selidbi ili izmjena u panelu. Pomaže kratak postupak provjere:

  1. Provjeriti djelotvorne vrijednosti u web-kontekstu, a ne samo u naredbenom retku, primjerice kratko odloženom datotekom za provjeru koja se odmah zatim briše.
  2. Provjeriti debug način svake aplikacije u njezinoj konfiguracijskoj datoteci.
  3. Isporučene stranice pretražiti na tipične tekstove pogrešaka, kao u bloku koda ispod.
  4. U tražilici upitom site: na Vašu domenu tražiti pojmove poput „Fatal error“ ili „Warning“.
  5. Provjeriti upisuje li se u zapisnik pogrešaka i da se ne nalazi u web-korijenu.
# Pretražiti isporučene stranice na tekstove PHP pogrešaka (samo vlastite domene)
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
# Upisuje li se u zapisnik pogrešaka?
ls -l /var/log/php/
Važno

Skrivanje pogrešaka nije zamjena za njihovo otklanjanje. Zapisnik pun upozorenja znak je potrebe za održavanjem, a nakon provale često je važan trag. Što pritom zapisivati, a što ne, opisuje članak Sigurno zapisivati: bilježiti pogreške bez curenja podataka.

Zaključak: tiho u pregledniku, govorljivo u zapisniku

Pravilo za produkcijske poslužitelje je jednostavno: pogreške pripadaju u zapisnik, a ne na web-stranicu. U praksi ga ometaju zadane vrijednosti koje nisu zamišljene za produkciju, debug sklopke u aplikacijama i konfiguracije koje se nakon ažuriranja ili selidbi vrate unatrag.

Tko isključi display_errors i display_startup_errors, zaključa vrijednosti u poolu, provjeri debug način aplikacije i redovito provjerava rezultat, zatvara jedan od najčešćih izvora nepotrebnog odavanja informacija. Trud je malen, a učinak traje dok provjera ostaje dio svakog ažuriranja.

Jednu točku ne treba previdjeti: zapisnik pogrešaka nije kanta za smeće. Tko ga redovito čita, prepoznaje pogrešna ažuriranja, zastarjele funkcije, a ponekad i prve tragove napada, dugo prije nego što kupci išta primijete.

Kako PHP SOS konkretno pomaže?

  • Provjeriti: očitavamo djelotvorne postavke pogrešaka po web-stranici i poolu te pretražujemo isporučene stranice na ispise pogrešaka.
  • Prebaciti: PHP i postavke aplikacije postavljamo za produkcijski rad i zaključavamo ih od nadjačavanja.
  • Postaviti zapisnike: zapisnici pogrešaka nalaze se izvan web-korijena, rotiraju se i dostupni su Vašim programerima.
  • Zadržati trajno: u sigurnosnom ugovoru o održavanju postavke ponovno provjeravamo nakon svakog ažuriranja.

Česta pitanja

Nije li display_errors u PHP-u ionako isključen?

Nije automatski. Prema PHP priručniku ugrađena zadana vrijednost display_errors je 1. Tek isporučeni predložak php.ini-production postavlja Off. Koristi li Vaš poslužitelj taj predložak, ovisi o distribuciji, panelu ili image-u kontejnera i treba provjeriti.

Je li display_errors = Off dovoljan ako WordPress ili Laravel rade u debug načinu?

Nije. Mnogi CMS-ovi i frameworki donose vlastite stranice s pogreškama koje neovisno o PHP-u mogu prikazivati pojedinosti. Zato isključite i debug način aplikacije, primjerice WP_DEBUG_DISPLAY kod WordPressa ili APP_DEBUG kod Laravela i Symfonyja.

Kamo idu pogreške kad se više ne prikazuju?

Uz log_errors = On PHP ih upisuje u datoteku koju navodi error_log ili u zapisnik dotičnog načina rada, primjerice zapisnik pogrešaka Apachea ili PHP-FPM-a. Datoteka bi trebala biti izvan web-korijena i redovito se rotirati.

Kakve veze fatal_error_backtraces ima s PHP2Shellom?

Postavka postoji od PHP-a 8.5 i zadano je aktivna. php.net navodi fatal_error_backtraces=0 s naknadnim ponovnim pokretanjem kao jednu od prijelaznih mjera za PHP 8.5 dok ažuriranje na 8.5.12 još nije provedeno. Ne zamjenjuje ažuriranje.

Izvori

Hitni kontakt

Svaki sat se računa. Pišite nam odmah.

Ukratko opišite sustav, verziju PHP-a i opažanje. Javit ćemo Vam se, razjasniti situaciju i raditi na daljinu dok incident nije zaključen i dokumentiran.

Hitna pomoć