Kort sagt: Logning i PHP med blik for databeskyttelse betyder: registrér sikkerhedsrelevante hændelser fuldstændigt, men skriv aldrig adgangskoder, tokens, sessionsidentifikatorer og følsomme kundedata i loggen. Fejl hører hjemme i loggen, ikke på skærmen, logge ligger uden for webroot og er beskyttet mod ændring. Hvor længe logge bliver, afgør I bevidst sammen med databeskyttelsesrådgiveren.
Mellem sporsikring og datalæk
Efter PHP2Shell rådede fagmedier til at opbevare webserver-logge fra 20.10.2026. Den, der ville gennemføre det, konstaterede ofte to ting. Enten var loggene for længst roteret og slettet. Eller de indeholdt ting, som aldrig burde have stået dér: fuldstændige formularinput, adgangskoder fra mislykkede logins, API-nøgler i URL'er.
Begge dele er et problem. Uden logge kan en hændelse næppe rekonstrueres. Med for meget indhold bliver selve loggen et mål, for den, der får adgang til serveren, læser den gerne med. God logning ligger imellem: nok til sporsøgningen, så lidt som muligt af beskyttelsesværdige data.
Hvad en PHP-applikation bør logge
OWASP Logging Cheat Sheet nævner hændelser, der tæller for sikkerhed og sporbarhed. For typiske PHP-applikationer kan de sammenfattes sådan:
| I loggen | Ikke i loggen |
|---|---|
| vellykkede og mislykkede logins | adgangskoder, også forkert indtastede |
| mislykkede rettighedskontroller | sessionsidentifikatorer i klartekst |
| ændringer af konti og rettigheder | access-tokens og API-nøgler |
| fejl ved inputkontrol | adgangsdata til databasen |
| uploads, importer og eksporter | betalings- og bankdata |
| konfigurationsændringer, start og stop | sundhedsdata og andre særligt beskyttelsesværdige data |
| kørselsfejl med sted, uden brugsdata | fuldstændigt formularindhold |
Hver post bør besvare spørgsmålene hvornår, hvor, hvem og hvad: tidsstempel, applikation og vært, kildeadresse, brugeridentifikator, hændelsens art og resultat. Navne eller mailadresser kan ofte maskeres eller erstattes af en intern identifikator uden at miste nytten.
To kilder til uønskede data i loggen overses ofte. Den første er URL'er: Står et token, en nøgle til nulstilling af adgangskode eller en mailadresse i query-strengen, havner den automatisk i webserverens access-log, i proxy-logge og i browserhistorikken. Sådanne værdier hører hjemme i request-body eller en header, ikke i adressen. Den anden kilde er debug-tilstanden. Frameworks og plugins skriver i debug-drift ofte fuldstændige forespørgsler, databaseforespørgsler og miljøvariabler med. Forbliver denne tilstand aktiv efter en fejlsøgning, vokser der ubemærket en fil med netop de oplysninger, en angriber søger. Kontrollér efter hver fejlsøgning, om debug-output er slået fra igen, og slet de filer, der er opstået herved.
Logning i PHP: grundindstillingerne
Det første niveau er PHP selv. I produktion skal fejl logges, men ikke udskrives. Loggen ligger uden for webroot, så den ikke kan hentes via en URL.
; php.ini eller FPM-pool til produktion
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/app-error.log
Hvorfor synlige fejl er farlige, beskriver Slå fejlvisning fra i produktion. Hvordan fejl og exceptions hænger sammen i PHP, forklarer Fejl og exceptions i PHP.
Det andet niveau er applikationen. Mange frameworks bruger hertil et bibliotek efter standarden PSR-3 fra PHP-FIG, der fastlægger en ensartet logger-grænseflade. Vigtigt er ikke biblioteket, men disciplinen: Vælg kontekstdata bevidst i stedet for at skrive hele forespørgsler eller objekter i loggen.
<?php
// Uskadeliggør og maskér input før logning
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'] ?? '',
// aldrig: 'passwort' => $_POST['passwort']
]);
Log-injection og manipulerede poster
Skriver en applikation input ufiltreret i loggen, kan en angriber med linjeskift skabe forfalskede poster. Det forvirrer analysen og kan skjule spor. OWASP Cheat Sheet anbefaler strukturerede formater som JSON, fjernelse eller kodning af linjeskift og en længdebegrænsning for input i loggen.
Lige så vigtig er beskyttelsen af selve loggene:
- Placering uden for webroot og med rettigheder, som webserver-brugeren har brug for til at skrive, men ikke til at slette gamle filer.
- Kopi til et andet system, f.eks. via syslog over en krypteret forbindelse. Den, der overtager serveren, skal ikke bare kunne slette sporene.
- Begræns læseadgangen og log den selv. Logge indeholder næsten altid personoplysninger.
- Opdag svigt: Bliver loggen pludselig tom, er det et advarselstegn.
- Afstem klokkeslættet: Alle servere henter tiden fra samme kilde og skriver en entydig tidszone i loggen. Ellers kan poster fra webserver, PHP og database efter en hændelse næppe samles til en tidslinje.
En log, der kun ligger på den kompromitterede server, er svag som bevismiddel. En løbende kopi på et adskilt system er efter en hændelse ofte den eneste pålidelige kilde.
Træf bevidst beslutning om opbevaring og databeskyttelse
Hvor længe logge må og skal blive, er en afvejning mellem sikkerhedsinteresse, dataminimering og lovmæssige eller kontraktlige krav. Art. 32 GDPR kræver tekniske og organisatoriske foranstaltninger, der står i forhold til risikoen, blandt andet for varigt at sikre systemernes fortrolighed, integritet og tilgængelighed; logning kan bidrage hertil. Samtidig må personoplysninger ikke gemmes længere end nødvendigt.
Fastlæg derfor en frist pr. logtype, skriv begrundelsen ned, og afstem begge dele med jeres databeskyttelsesrådgiver. Til en igangværende undersøgelse kan det være nødvendigt at sikre logge ud over den normale frist. Det bør så ligeledes dokumenteres. Denne side er generel information og ingen retsrådgivning; ved konkrete spørgsmål hjælper databeskyttelsesrådgivere og advokat. Hvordan I analyserer logge efter et angreb, viser Analysér webserver-logs efter et angreb.
Hvordan hjælper PHP SOS konkret?
- Vi kontrollerer jeres eksisterende logge for adgangskoder, tokens og andre data, der ikke hører hjemme dér.
- Vi indstiller PHP og applikation, så fejl logges, men ikke vises.
- Vi indretter en beskyttet kopi af loggene på et adskilt system.
- Via security-monitoring analyserer vi løbende sikkerhedsrelevante poster og melder det påfaldende forståeligt.
Konklusion: Gode logge er sparsomme i indholdet og generøse i beskyttelsen. Den, der i dag fastlægger, hvad der logges, og hvad aldrig, har i alvorlige tilfælde brugbare spor og intet ekstra datalæk.
Ofte stillede spørgsmål
Må IP-adresser stå i logfiler?
IP-adresser kan være personoplysninger. Om og hvor længe I gemmer dem, afhænger af formål og retsgrundlag. Afklar omfang og opbevaring med jeres databeskyttelsesrådgiver; denne side er ingen retsrådgivning.
Hvor længe bør man opbevare logge?
Så længe det er nødvendigt og retligt tilladt for sikkerhed og fejlsøgning, og ikke længere. Efter PHP2Shell anbefalede fagpressen at opbevare webserver-logge fra 20.10.2026. Fastlæg frister bevidst, og dokumentér dem.
Hvad er log-injection?
Indeholder et input linjeskift eller kontroltegn og skrives det ufiltreret i loggen, kan det skabe forfalskede poster. Det forvrænger analyser. Strukturerede formater som JSON og fjernelse af linjeskift forhindrer det.
Skal display_errors være slået fra i produktion?
Ja. Fejl skal i loggen, ikke i outputtet til besøgende. Synlige fejlmeddelelser afslører stier, forespørgsler og undertiden adgangsdata.