Ukratko: Logiranje u PHP-u s pogledom na zaštitu podataka znači: sigurnosno relevantne događaje bilježiti potpuno, a lozinke, tokene, identifikatore sesija i osjetljive podatke kupaca nikad upisivati u zapisnik. Pogreške pripadaju u zapisnik, a ne na ekran, zapisnici leže izvan webroota i zaštićeni su od promjene. Koliko dugo zapisnici ostaju, odlučujete svjesno zajedno sa službenikom za zaštitu podataka.
Između osiguravanja tragova i curenja podataka
Nakon PHP2Shella stručni su mediji savjetovali čuvati zapisnike web-poslužitelja od 20. 10. 2026. Tko je to htio provesti, često je utvrdio dvije stvari. Ili su zapisnici odavno rotirani i obrisani. Ili su sadržavali stvari koje tamo nikad nisu smjele stajati: potpune unose obrazaca, lozinke iz neuspjelih prijava, API ključeve u URL-ovima.
Oboje je problem. Bez zapisnika incident se jedva može rekonstruirati. S previše sadržaja zapisnik i sam postaje meta, jer tko dobije pristup poslužitelju, rado ga čita. Dobro logiranje leži između: dovoljno za potragu za tragovima, što manje podataka koje treba štititi.
Što PHP aplikacija treba bilježiti
OWASP Logging Cheat Sheet navodi događaje koji su važni za sigurnost i sljedivost. Za tipične PHP aplikacije mogu se ovako sažeti:
| U zapisnik | Ne u zapisnik |
|---|---|
| uspješne i neuspjele prijave | lozinke, i pogrešno unesene |
| neuspjele provjere ovlasti | identifikatori sesija u otvorenom tekstu |
| promjene računa i prava | access tokeni i API ključevi |
| pogreške pri provjeri unosa | pristupni podaci za bazu podataka |
| uploadi, uvozi i izvozi | podaci o plaćanju i bankovnim računima |
| promjene konfiguracije, pokretanje i zaustavljanje | zdravstveni podaci i drugi osobito zaštićeni podaci |
| pogreške izvođenja s lokacijom, bez korisničkih podataka | potpuni sadržaji obrazaca |
Svaki unos trebao bi odgovoriti na pitanja kada, gdje, tko i što: vremenska oznaka, aplikacija i host, izvorna adresa, identifikator korisnika, vrsta događaja i ishod. Imena ili adrese e-pošte često se mogu maskirati ili zamijeniti internim identifikatorom a da se korist ne izgubi.
Dva izvora neželjenih podataka u zapisniku često se previde. Prvi su URL-ovi: ako token, ključ za reset lozinke ili adresa e-pošte stoji u query stringu, automatski završava u access zapisniku web-poslužitelja, u proxy zapisnicima i u povijesti preglednika. Takve vrijednosti pripadaju u tijelo zahtjeva ili zaglavlje, a ne u adresu. Drugi izvor je debug način. Frameworci i dodaci u debug radu često zapisuju potpune zahtjeve, upite prema bazi podataka i varijable okruženja. Ako taj način ostane aktivan nakon traženja pogrešaka, neprimjetno raste datoteka upravo s informacijama koje napadač traži. Nakon svakog traženja pogrešaka provjerite jesu li debug ispisi ponovno isključeni i obrišite datoteke koje su pritom nastale.
Logiranje u PHP-u: osnovne postavke
Prva razina je sam PHP. U produkciji se pogreške trebaju bilježiti, ali ne ispisivati. Zapisnik leži izvan webroota kako ne bi bio dostupan preko URL-a.
; php.ini ili FPM pool za produkciju
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/app-error.log
Zašto su vidljive pogreške opasne, opisuje članak Isključiti ispis pogrešaka u produkciji. Kako su pogreške i iznimke u PHP-u povezane, objašnjava Pogreške i iznimke u PHP-u.
Druga razina je aplikacija. Mnogi frameworci za to koriste biblioteku prema standardu PSR-3 organizacije PHP-FIG, koji utvrđuje jedinstveno sučelje za logger. Važna nije biblioteka, nego disciplina: svjesno birati podatke konteksta umjesto da se u zapisnik upisuju cijeli zahtjevi ili objekti.
<?php
// Unose neutralizirati i maskirati prije logiranja
function logSicher(string $text): string {
return mb_substr(str_replace(["\r", "\n"], ' ', $text), 0, 200);
}
function maskiereMail(string $mail): string {
[$name, $domain] = array_pad(explode('@', $mail, 2), 2, '');
return mb_substr($name, 0, 1) . '***@' . $domain;
}
$logger->warning('Anmeldung fehlgeschlagen', [
'benutzer' => maskiereMail(logSicher($_POST['email'] ?? '')),
'ip' => $_SERVER['REMOTE_ADDR'] ?? '',
// nikada: 'passwort' => $_POST['passwort']
]);
Log Injection i manipulirani unosi
Ako aplikacija nefiltrirane unose upisuje u zapisnik, napadač prijelomima redaka može stvoriti krivotvorene unose. To zbunjuje analizu i može prikriti tragove. OWASP Cheat Sheet preporučuje strukturirane formate poput JSON-a, uklanjanje ili kodiranje prijeloma redaka i ograničenje duljine za unose u zapisniku.
Jednako je važna zaštita samih zapisnika:
- Pohrana izvan webroota i s pravima koja korisniku web-poslužitelja trebaju za pisanje, ali ne i za brisanje starih datoteka.
- Kopija na drugi sustav, primjerice putem syslog-a preko šifrirane veze. Tko preuzme poslužitelj, ne bi smio jednostavno moći obrisati tragove.
- Ograničiti pristup za čitanje i sam ga bilježiti. Zapisnici gotovo uvijek sadrže osobne podatke.
- Prepoznati ispad: ako zapisnik odjednom ostane prazan, to je znak upozorenja.
- Uskladiti vrijeme: svi poslužitelji vrijeme preuzimaju iz istog izvora i u zapisnik upisuju jednoznačnu vremensku zonu. Inače se unosi web-poslužitelja, PHP-a i baze podataka nakon incidenta jedva mogu sastaviti u vremenski slijed.
Zapisnik koji leži samo na kompromitiranom poslužitelju slabo je dokazno sredstvo. Tekuća kopija na odvojenom sustavu nakon incidenta je često jedini pouzdan izvor.
Čuvanje i zaštita podataka: odlučiti svjesno
Koliko dugo zapisnici smiju i moraju ostati, odvagivanje je između sigurnosnog interesa, štednje podataka i zakonskih ili ugovornih zahtjeva. Čl. 32. GDPR-a traži tehničke i organizacijske mjere primjerene riziku, među ostalim radi trajnog osiguravanja povjerljivosti, cjelovitosti i raspoloživosti sustava; bilježenje tome može pridonijeti. Istodobno se osobni podaci ne smiju spremati dulje nego što je potrebno.
Zato utvrdite rok za svaku vrstu zapisnika, zapišite obrazloženje i oboje uskladite sa svojim službenikom za zaštitu podataka. Za tekuću istragu može biti potrebno osigurati zapisnike preko uobičajenog roka. To bi tada također trebalo dokumentirati. Ova stranica opća je informacija i nije pravni savjet; kod konkretnih pitanja pomažu službenik za zaštitu podataka i odvjetnik. Kako zapisnike analizirati nakon napada, pokazuje Analizirati zapisnike web-poslužitelja nakon napada.
Kako PHP SOS konkretno pomaže?
- Provjeravamo Vaše postojeće zapisnike na lozinke, tokene i druge podatke koji tamo ne pripadaju.
- PHP i aplikaciju postavljamo tako da se pogreške bilježe, ali ne prikazuju.
- Postavljamo zaštićenu kopiju zapisnika na odvojenom sustavu.
- Preko sigurnosnog nadzora kontinuirano analiziramo sigurnosno relevantne unose i razumljivo prijavljujemo upadljivo.
Zaključak: Dobri zapisnici su štedljivi sa sadržajem i velikodušni sa zaštitom. Tko danas utvrdi što se bilježi, a što nikad, u najgorem će slučaju imati iskoristive tragove, a ne dodatno curenje podataka.
Česta pitanja
Smiju li IP adrese stajati u zapisnicima?
IP adrese mogu biti osobni podaci. Hoćete li ih i koliko dugo spremati, ovisi o svrsi i pravnoj osnovi. Opseg i čuvanje razjasnite sa svojim službenikom za zaštitu podataka; ova stranica nije pravni savjet.
Koliko dugo treba čuvati zapisnike?
Onoliko koliko je potrebno za sigurnost i traženje pogrešaka te pravno dopušteno, a ne dulje. Nakon PHP2Shella stručni su mediji preporučivali čuvati zapisnike web-poslužitelja od 20. 10. 2026. Rokove utvrdite svjesno i dokumentirajte ih.
Što je Log Injection?
Ako unos sadrži prijelome redaka ili kontrolne znakove i upiše se nefiltriran u zapisnik, može stvoriti krivotvorene unose. To iskrivljuje analize. Strukturirani formati poput JSON-a i uklanjanje prijeloma redaka to sprječavaju.
Treba li display_errors u produkciji biti isključen?
Da. Pogreške trebaju ići u zapisnik, a ne u izlaz posjetiteljima. Vidljive poruke o pogreškama otkrivaju putanje, upite, a ponekad i pristupne podatke.