# Bezpečné logování: protokolovat chyby bez úniku dat

> Protokolování chyb a událostí v PHP bez úniku hesel, tokenů nebo dat zákazníků: co do logu patří, co ne a jak ho chránit. S příklady a nastavením.

Zdroj: https://phpsos.de/cs/blog/sicher-loggen-php/  
Stav: 25.10.2026  
Poskytovatel: PHP SOS, Nouzová pomoc pro PHP a bezpečnost serverů. Okamžitá pomoc přes WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20den%2C%20PHP%20SOS%2C%20pot%C5%99ebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20PHP%20serverem.%20Firma%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručně:** Logování v PHP s ohledem na ochranu osobních údajů znamená: bezpečnostně relevantní události zaznamenat úplně, hesla, tokeny, identifikátory relací a citlivá data zákazníků ale nikdy do logu nezapisovat. Chyby patří do protokolu, ne na obrazovku, logy leží mimo webroot a jsou chráněny proti změně. Jak dlouho logy zůstanou, rozhodněte vědomě společně s pověřencem pro ochranu osobních údajů.

## Mezi zajištěním stop a únikem dat

Po PHP2Shell radila odborná média uchovávat logy webserveru od 20. 10. 2026. Kdo to chtěl provést, často zjistil dvojí. Buď byly logy dávno rotovány a smazány. Nebo obsahovaly věci, které tam nikdy neměly být: úplné vstupy formulářů, hesla z neúspěšných přihlášení, klíče API v URL.

Obojí je problém. Bez logů lze incident sotva rekonstruovat. S příliš velkým obsahem se samotný log stává cílem, protože kdo získá přístup k serveru, rád si ho přečte. Dobré logování leží mezi tím: dost pro hledání stop, co nejméně chráněných dat.

## Co by aplikace PHP měla protokolovat

OWASP Logging Cheat Sheet uvádí události, které se počítají pro bezpečnost a dohledatelnost. Pro typické aplikace PHP je lze shrnout takto:

| Do logu | Ne do logu |
|---|---|
| úspěšná a neúspěšná přihlášení | hesla, i chybně zadaná |
| neúspěšné kontroly oprávnění | identifikátory relací v čitelné podobě |
| změny účtů a práv | přístupové tokeny a klíče API |
| chyby při kontrole vstupu | přístupové údaje k databázi |
| uploady, importy a exporty | platební a bankovní údaje |
| změny konfigurace, start a zastavení | zdravotní údaje a jiná zvlášť chráněná data |
| chyby za běhu s místem, bez užitných dat | úplný obsah formulářů |

Každý záznam by měl odpovídat na otázky kdy, kde, kdo a co: časové razítko, aplikace a hostitel, zdrojová adresa, identifikátor uživatele, druh události a výsledek. Jména nebo e-mailové adresy lze často maskovat nebo nahradit interním identifikátorem, aniž by se ztratil užitek.

Dva zdroje nechtěných dat v logu se často přehlížejí. První jsou URL: pokud token, klíč k resetu hesla nebo e-mailová adresa stojí v query stringu, skončí automaticky v přístupovém logu webserveru, v lozích proxy a v historii prohlížeče. Takové hodnoty patří do těla požadavku nebo do hlavičky, ne do adresy. Druhým zdrojem je ladicí režim. Frameworky a pluginy v ladicím provozu často zapisují úplné požadavky, databázové dotazy a proměnné prostředí. Pokud tento režim po hledání chyby zůstane aktivní, nepozorovaně roste soubor přesně s informacemi, které útočník hledá. Po každém hledání chyby zkontrolujte, zda jsou ladicí výstupy opět vypnuty, a smažte soubory, které při tom vznikly.

## Logování v PHP: základní nastavení

První úrovní je samotné PHP. V produkci se mají chyby protokolovat, ale nevypisovat. Log leží mimo webroot, aby nebyl dostupný přes URL.

```ini
; php.ini nebo pool FPM pro produkci
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/app-error.log
```

Proč jsou viditelné chyby nebezpečné, popisuje článek [Vypnutí výpisu chyb v produkci](https://phpsos.de/cs/blog/display-errors-produktion/). Jak spolu chyby a výjimky v PHP souvisejí, vysvětluje stránka [Chyby a výjimky v PHP](https://phpsos.de/cs/php/fehler-und-exceptions/).

Druhou úrovní je aplikace. Mnoho frameworků k tomu používá knihovnu podle standardu PSR-3 od PHP-FIG, který stanoví jednotné rozhraní loggeru. Důležitá není knihovna, ale disciplína: kontextová data vybírat vědomě, místo aby se do logu zapisovaly celé požadavky nebo objekty.

```php
<?php
// Vstupy před zalogováním zneškodnit a maskovat
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'] ?? '',
    // nikdy: 'passwort' => $_POST['passwort']
]);
```

## Log injection a manipulované záznamy

Pokud aplikace zapisuje vstupy do logu nefiltrovaně, může útočník pomocí zalomení řádků vytvářet padělané záznamy. To mate vyhodnocení a může zakrýt stopy. OWASP Cheat Sheet doporučuje strukturované formáty jako JSON, odstranění nebo kódování zalomení řádků a omezení délky vstupů v logu.

Stejně důležitá je ochrana samotných logů:

1. **Uložení mimo webroot** a s právy, která uživatel webserveru potřebuje k zápisu, ale ne k mazání starých souborů.
2. **Kopie na druhý systém**, například přes syslog po šifrovaném spojení. Kdo server převezme, nesmí snadno smazat stopy.
3. **Omezit přístup ke čtení** a sám ho protokolovat. Logy obsahují téměř vždy osobní údaje.
4. **Rozpoznat výpadek:** Pokud je log náhle prázdný, je to varovné znamení.
5. **Sladit čas:** Všechny servery přebírají čas ze stejného zdroje a do logu zapisují jednoznačné časové pásmo. Jinak lze záznamy webserveru, PHP a databáze po incidentu jen těžko složit do časové osy.

> **Důležité:**
> Log, který leží jen na napadeném serveru, je jako důkazní prostředek slabý. Průběžná kopie na odděleném systému je po incidentu často jediným spolehlivým zdrojem.

## Uchovávání a ochranu osobních údajů rozhodnout vědomě

Jak dlouho smějí a musí logy zůstat, je vážení mezi bezpečnostním zájmem, šetřením daty a zákonnými či smluvními požadavky. Čl. 32 GDPR vyžaduje technická a organizační opatření přiměřená riziku, mimo jiné k trvalému zajištění důvěrnosti, integrity a dostupnosti systémů; protokolování k tomu může přispět. Zároveň se osobní údaje nesmějí ukládat déle, než je nutné.

Stanovte proto lhůtu pro každý druh logu, napište odůvodnění a obojí odsouhlaste se svým pověřencem pro ochranu osobních údajů. Pro probíhající vyšetřování může být nutné zajistit logy i nad rámec běžné lhůty. To by se pak mělo rovněž zdokumentovat. Tato stránka je obecná informace a není právním poradenstvím; při konkrétních otázkách pomohou pověřenec pro ochranu osobních údajů a advokát. Jak logy po útoku vyhodnotit, ukazuje [Vyhodnocení logů webserveru po útoku](https://phpsos.de/cs/ratgeber/logfiles-auswerten/).

## Jak konkrétně pomáhá PHP SOS?

- Zkontrolujeme vaše stávající logy na hesla, tokeny a další data, která tam nepatří.
- PHP a aplikaci nastavíme tak, aby se chyby protokolovaly, ale nezobrazovaly.
- Zavedeme chráněnou kopii logů na odděleném systému.
- Prostřednictvím [bezpečnostního monitoringu](https://phpsos.de/cs/leistungen/security-monitoring/) průběžně vyhodnocujeme bezpečnostně relevantní záznamy a nápadnosti hlásíme srozumitelně.

**Závěr:** Dobré logy jsou úsporné v obsahu a štědré v ochraně. Kdo dnes stanoví, co se protokoluje a co nikdy, bude mít v krizovém případě využitelné stopy a žádný další únik dat.


## Časté dotazy

**Smějí být adresy IP v souborech logu?**  
Adresy IP mohou být osobními údaji. Zda a jak dlouho je ukládáte, závisí na účelu a právním základu. Rozsah a uchovávání ujasněte s pověřencem pro ochranu osobních údajů; tato stránka není právní poradenství.

**Jak dlouho by se měly logy uchovávat?**  
Tak dlouho, jak je to nutné pro bezpečnost a hledání chyb a právně přípustné, a ne déle. Po PHP2Shell doporučoval odborný tisk uchovávat logy webserveru od 20. 10. 2026. Lhůty stanovte vědomě a zdokumentujte je.

**Co je log injection?**  
Pokud vstup obsahuje zalomení řádků nebo řídicí znaky a zapíše se do logu nefiltrovaně, může vytvořit padělané záznamy. To zkresluje vyhodnocení. Strukturované formáty jako JSON a odstranění zalomení řádků tomu zabrání.

**Má být display_errors v produkci vypnuto?**  
Ano. Chyby patří do logu, ne do výstupu pro návštěvníky. Viditelná chybová hlášení prozrazují cesty, dotazy a někdy přístupové údaje.

## Zdroje

- [OWASP: Logging Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html)
- [PHP-FIG: standardy PSR](https://www.php-fig.org/)
- [Příručka PHP](https://www.php.net/manual/de/)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
