Situația actuală: PHP2Shell. Două vulnerabilități critice PHP (CVSS 9.2) permit cod malițios fără autentificare. Patchuri din 21.10.2026.Ce este de făcut acum →

display_errors off: dezactivarea ieșirilor de erori în producție

Mesajele de eroare PHP vizibile dezvăluie căi, nume de baze de date și versiuni. Cum le dezactivați în PHP, în framework și în serverul web, fără a pierde erorile din vedere.

Stadiu 6 min de cititSecurizare și configurare

Pe scurt: Pe un site live, display_errors = Off aparține în php.ini, împreună cu display_startup_errors = Off, log_errors = On și un jurnal de erori în afara webroot-ului. În plus, CMS-urile și framework-urile trebuie să ruleze în modul de producție, altfel propriile lor pagini de eroare arată detaliile. Blocate cu php_admin_flag și verificate după fiecare actualizare, erorile rămân în jurnal, nu în browser.

Ce dezvăluie un singur mesaj de eroare

Un avertisment în marginea de sus a paginii, un „Fatal error” în loc de rezumatul comenzii: astfel de ieșiri par inofensive. Pentru un atacator sunt o hartă. Ele arată căi complete de fișiere, nume de baze de date și de tabele, biblioteci folosite și adesea versiunea PHP.

Tocmai în situații precum PHP2Shell, în care se caută în masă servere vulnerabile, un server ar trebui să dezvăluie cât mai puțin despre sine. Asta nu închide nicio vulnerabilitate din interpretorul PHP, dar îngreunează fiecare pas ulterior după o intruziune și face mai anevoioase atacurile țintite asupra aplicației dumneavoastră.

Se adaugă protecția datelor. Mesajele de eroare pot conține părți din cereri, de exemplu adrese de e-mail din formulare. Ce apare în browserul unui vizitator nu mai este sub controlul dumneavoastră.

Valorile implicite nu sunt gândite pentru producție

Mulți pleacă de la ideea că PHP ascunde erorile de la sine. Manualul PHP spune altceva: valoarea implicită încorporată a display_errors este 1, iar display_startup_errors este, începând cu PHP 8.0, de asemenea activat implicit. Abia șablonul livrat php.ini-production setează ambele pe Off. Manualul numește explicit display_errors o funcție de dezvoltare, care nu ar trebui folosită niciodată pe sisteme din internet.

Dacă serverul dumneavoastră folosește șablonul de producție nu este de la sine înțeles. Imaginile de container pornesc uneori complet fără php.ini, panourile de hosting stabilesc valori proprii, iar după o mutare se copiază bucuros șablonul de dezvoltare.

display_errors off: setările pe scurt

Valorile următoare sunt rezonabile pentru serverele de producție. Constantele precum E_ALL funcționează doar în php.ini; în configurația Apache, potrivit manualului PHP, nu au nicio semnificație și trebuie indicate ca număr.

Setare Producție Scop
display_errors Off fără erori în browser
display_startup_errors Off fără erori la pornirea PHP în ieșire
log_errors On scrierea erorilor în jurnal
error_log cale în afara webroot-ului fișier de jurnal propriu pentru fiecare site sau pool
error_reporting E_ALL înregistrarea tuturor erorilor, nu afișarea
html_errors Off text simplu în loc de HTML în jurnale
zend.exception_ignore_args On fără argumentele funcțiilor în stacktrace-uri
fatal_error_backtraces 0 până la actualizare (doar PHP 8.5) măsură provizorie conform php.net

zend.exception_ignore_args este deosebit de valoroasă. Fără această setare, stacktrace-urile din jurnale și de pe paginile de eroare pot conține argumentele apelurilor de funcții, deci și parole sau token-uri care tocmai erau prelucrate.

; php.ini al SAPI web
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
; doar PHP 8.5, măsură provizorie până la actualizarea la 8.5.12:
; fatal_error_backtraces = 0

În pool-ul FPM blocați suplimentar valorile cele mai importante, pentru ca nicio aplicație să nu le reactiveze prin ini_set():

; de ex. /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

Apoi reporniți serviciul PHP respectiv. Cum funcționează exact blocarea explică articolul php_admin_value: blocarea setărilor împotriva suprascrierii. O configurație de bază completă găsiți la Configurarea sigură a php.ini.

Al doilea comutator: modul debug al aplicației

PHP este doar jumătate din treabă. Framework-urile moderne prind singure erorile și arată pagini de eroare proprii, adesea foarte detaliate. În modul debug, ele conțin extrase din codul sursă, valori de configurare și uneori variabile de mediu. Aceste pagini apar chiar și atunci când display_errors este dezactivat în PHP.

Verificați de aceea, pentru fiecare aplicație, comutatorul ei propriu. La WordPress sunt WP_DEBUG și WP_DEBUG_DISPLAY în wp-config.php, la Laravel și Symfony APP_DEBUG și mediul din fișierul .env, la alte sisteme modul de producție conform documentației producătorului. Pe un sistem live, modul debug trebuie să rămână permanent oprit; chiar și „doar puțin, pentru test” este un risc.

Cum sunt tratate curat erorile în aplicație, în loc să fie suprimate, descrie Erori și excepții în PHP.

Cum găsiți ieșirile de erori înainte să o facă alții

Nu este suficient să configurați o dată. Ieșirile de erori revin după actualizări, mutări sau modificări în panou. Un scurt flux de verificare ajută:

  1. Verificați valorile efective în contextul web, nu doar în linia de comandă, de exemplu cu un fișier de verificare depus pe scurt și șters imediat după aceea.
  2. Controlați modul debug al fiecărei aplicații în fișierul ei de configurare.
  3. Căutați în paginile livrate texte tipice de eroare, ca în blocul de cod de mai jos.
  4. Căutați în motorul de căutare, cu o interogare site: pe domeniul dumneavoastră, termeni precum „Fatal error” sau „Warning”.
  5. Verificați dacă în jurnalul de erori se scrie și dacă nu se află în webroot.
# Căutarea în paginile livrate a textelor de eroare PHP (doar domenii proprii)
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
# Se scrie în jurnalul de erori?
ls -l /var/log/php/
Important

A ascunde erorile nu înlocuiește remedierea lor. Un jurnal plin de avertismente este un indiciu de nevoie de întreținere, iar după o intruziune este adesea o urmă importantă. Ce înregistrați și ce nu descrie Jurnalizare sigură: înregistrarea erorilor fără scurgere de date.

Concluzie: silențios în browser, vorbăreț în jurnal

Regula pentru serverele de producție este simplă: erorile aparțin jurnalului, nu site-ului. În practică eșuează din cauza valorilor implicite care nu sunt gândite pentru producție, a comutatoarelor de debug din aplicații și a configurațiilor care revin la starea veche după actualizări sau mutări.

Cine dezactivează display_errors și display_startup_errors, blochează valorile în pool, controlează modul debug al aplicației și verifică regulat rezultatul închide una dintre cele mai frecvente surse de dezvăluire inutilă de informații. Efortul este mic, efectul durează atâta timp cât verificarea rămâne parte a fiecărei actualizări.

Un punct nu ar trebui să se piardă: jurnalul de erori nu este un coș de gunoi. Cine îl citește regulat recunoaște actualizări defectuoase, funcții depășite și uneori primele urme ale unui atac, mult înainte ca clienții să observe ceva.

Cum ajută PHP SOS concret?

  • Verificare: Citim setările efective de erori pentru fiecare site și pool și căutăm în paginile livrate ieșiri de erori.
  • Trecere: Stabilim setările PHP și ale aplicației pentru funcționarea în producție și le blocăm împotriva suprascrierii.
  • Configurarea jurnalelor: Jurnalele de erori se află în afara webroot-ului, sunt rotite și accesibile dezvoltatorilor dumneavoastră.
  • Menținere durabilă: În contractul de mentenanță de securitate verificăm din nou setările după fiecare actualizare.

Întrebări frecvente

Nu este display_errors oricum dezactivat în PHP?

Nu automat. Potrivit manualului PHP, valoarea implicită încorporată a display_errors este 1. Abia șablonul livrat php.ini-production setează Off. Dacă serverul dumneavoastră folosește acest șablon depinde de distribuție, panou sau imaginea de container și ar trebui verificat.

Este suficient display_errors = Off dacă WordPress sau Laravel rulează în modul debug?

Nu. Multe CMS-uri și framework-uri vin cu pagini de eroare proprii, care pot afișa detalii independent de PHP. Dezactivați de aceea și modul debug al aplicației, de exemplu WP_DEBUG_DISPLAY la WordPress sau APP_DEBUG la Laravel și Symfony.

Unde ajung erorile dacă nu mai sunt afișate?

Cu log_errors = On, PHP le scrie în fișierul indicat de error_log sau în jurnalul modului de operare respectiv, de exemplu jurnalul de erori al Apache sau al PHP-FPM. Fișierul ar trebui să se afle în afara webroot-ului și să fie rotit regulat.

Ce legătură are fatal_error_backtraces cu PHP2Shell?

Setarea există începând cu PHP 8.5 și este activă implicit. php.net indică fatal_error_backtraces=0, urmat de repornire, drept una dintre măsurile provizorii pentru PHP 8.5, cât timp actualizarea la 8.5.12 este încă în așteptare. Ea nu înlocuiește actualizarea.

Surse

Contact imediat

Fiecare oră contează. Scrieți-ne acum.

Descrieți pe scurt sistemul, versiunea PHP și ce ați observat. Ne vom face auziți, clarificăm situația și lucrăm la distanță până când incidentul este încheiat și documentat.

Ajutor imediat