Aktuel situation: PHP2Shell. To kritiske PHP-sårbarheder (CVSS 9,2) tillader skadelig kode uden login. Rettelser siden 21.10.2026.Hvad der skal gøres nu →

Sikkerhedskodereview til PHP-projekter

Hvordan teams målrettet gennemgår egen PHP-kode for sikkerhedssårbarheder: typer af reviews, kritiske funktioner, fornuftige værktøjer og en tjekliste.

Status 5 min. læsetidSikker udvikling

Kort sagt: Et sikkerhedskodereview til PHP er en målrettet læsning af kildetekst med ét spørgsmål: Hvor kan fremmed input gøre noget, det ikke må? Gennemprøvede er to former, et review af hver ændring og et grundreview af hele projektet, støttet af statisk analyse med PHPStan eller Psalm. Sårbarheder i PHP-fortolkeren som PHP2Shell finder et review ikke, men til gengæld de mange fejl, der opstår i egen kode.

Hvorfor netop nu se på egen kode?

PHP2Shell har i den sidste oktoberuge 2026 først og fremmest beskæftiget administratorer. Patche, genstarte, dokumentere: Arbejdet lå på serveren. For udviklingsteams bliver der bagefter et ubehageligt spørgsmål tilbage. Hvis en angriber kan udføre kode via en anden sårbarhed, hvad finder han så i vores applikation? Og hvor mange af disse sårbarheder har vi selv skrevet?

OWASP Top 10 viser i årevis, at de fleste svagheder i webapplikationer ikke er eksotiske. Manglende adgangskontrol, injection og usikker konfiguration står højt. Det er fejl, som et trænet blik finder i kildeteksten, længe før en angriber prøver dem af.

Dertil kommer en praktisk grund. Mange virksomheder lader alligevel i øjeblikket deres servere kontrollere, patche og hærde. Den, der ser på den egen applikation i samme omgang, lukker hullet mellem drift og udvikling. En hærdet server med sårbar applikation forbliver angribelig, og en ren skrevet applikation på upatchet PHP ligeså.

Grundreview eller ændringsreview?

OWASP Cheat Sheet om Secure Code Review skelner mellem to typer, der i praksis supplerer hinanden:

Type Hvornår Omfang Mål
Grundreview (baseline) nyt projekt, stor release, efter en hændelse hele projektet, vægtet efter risiko registrere bestanden af svagheder
Ændringsreview (diff) hver pull request kun ændret kode forhindre nye fejl

Et grundreview efter en hændelse er særligt værdifuldt. Den, der netop har ryddet en server op, bør vide, om applikationen byder på yderligere indgangsveje. Ændringsreviewet holder niveauet rent bagefter, fordi hver ændring før sammenføjningen også læses under sikkerhedsaspekter.

Code review i PHP: Hvor sikkerhedsfejl hober sig op

I PHP-projekter er det værd at kigge målrettet på bestemte funktioner og mønstre. De er ikke forbudte, men hvert fund fortjener spørgsmålet, om fremmede data kan nå ind.

Mønster i koden Mulig risiko Uddybning
SQL via strengsammensætning med variabler SQL-injection Forhindr SQL-injection i PHP
unserialize() på data udefra Objektinjektion Usikker deserialisering i PHP
include eller require med variabel sti Indlæsning af fremmede filer Forhindr Local og Remote File Inclusion
exec(), system(), shell_exec(), proc_open() Kommandoudførelse Command injection
Output uden htmlspecialchars() Cross-site scripting kontekstrigtig escaping
== ved tokens eller hashes Typeomdannelse omgår kontroller hash_equals(), strikse sammenligninger
eval(), extract() på input Kode- eller variabelinjektion som regel fjernes uden erstatning

Et hurtigt første overblik lykkes med en enkel søgning. Den erstatter ikke et review, men viser, hvor man bør begynde:

# Fundsteder for risikable funktioner i egen kode (vendor udelukket)
grep -rnE "\b(unserialize|eval|extract|shell_exec|exec|system|passthru|proc_open)\s*\(" src/ app/ 2>/dev/null

Mindst lige så vigtigt er, hvad der mangler i koden. Kontrollerer hver controller, om den loggede bruger må se eller ændre netop dette datasæt? Begrænses uploads til type og placering? Sådanne huller finder ingen søgning efter funktionsnavne, kun læsning af forløbet.

Værktøjer, der bærer reviewet

Statisk analyse kontrollerer kode uden at udføre den. PHPStan og Psalm finder typefejl, utilgængelig kode og forkerte antagelser om returværdier. Psalm tilbyder desuden en taint-analyse, der følger, om data fra forespørgsler flyder ukontrolleret til kritiske steder. Begge kan skærpes trinvist, så også ældre projekter kan komme med. Et overblik giver Statisk analyse: PHPStan og Psalm.

# Statisk analyse i projektet, hæv niveauet trinvist
vendor/bin/phpstan analyse src --level=5
# Taint-analyse med Psalm
vendor/bin/psalm --taint-analysis

Værktøjer leverer henvisninger, ikke domme. Hvert fund kræver en vurdering, og en tom rapport betyder ikke, at applikationen er sikker.

Lige så vigtigt som at finde er at fastholde. Hvert fund bør registreres med fundsted, kort beskrivelse, vurdering af risikoen, anbefalet udbedring og status, helst direkte i teamets ticketsystem. Så kan det følges, hvad der er udbedret, hvad der bevidst er accepteret, og hvad der stadig er åbent. Efter udbedringen er et andet blik værd: Er årsagen fjernet eller kun det ene symptom? Dukker det samme mønster op andre steder i koden? En fejl, der én gang er lavet, sidder erfaringsmæssigt sjældent kun ét sted.

En tjekliste til jeres eget team

Til ændringsreviews har en kort, fast liste vist sig at fungere. Den hører hjemme i skabelonen til pull requests:

  1. Hvor kommer alle data fra, som denne ændring behandler, og kontrolleres de på serversiden?
  2. Bygges databaseforespørgsler udelukkende med pladsholdere?
  3. Er hvert output escaped til sin kontekst, altså HTML, attribut, JavaScript eller URL?
  4. Kontrollerer koden rettigheden til netop dette objekt, ikke blot loginnet?
  5. Havner adgangskoder, tokens eller personoplysninger i logge eller fejlmeddelelser?
  6. Står der hemmeligheder i koden eller i versionerede filer?
  7. Er der optaget nye afhængigheder, og vedligeholdes de?
Tip

Lad altid sikkerhedskritiske dele som login, rettighedsstyring, betalingsforløb og uploads læse af en anden person, som ikke har været med i koden. Det fremmede blik finder antagelser, som forfatteren anser for selvfølgelige.

Hvordan hjælper PHP SOS konkret?

  • Vi gennemfører sammen med specialiserede partnere et grundreview af jeres PHP-applikation, vægtet efter de dele med højest risiko.
  • Vi indretter PHPStan eller Psalm, så det passer til jeres projekts stade, og skriver tjeklisten til jeres pull requests.
  • Vi forbinder reviewet med et blik på server og konfiguration, for mange sårbarheder opstår først i samspillet.
  • Hvor en kontrol udefra ønskes, supplerer vi reviewet med sikkerhedsaudit og penetrationstest.

Konklusion: Et code review er det billigste sted at udbedre sikkerhedsfejl, nemlig før de leveres. Den, der kontrollerer hver ændring med en kort liste og lejlighedsvis gennemser projektet fuldstændigt, mindsker angrebsfladen varigt.

Ofte stillede spørgsmål

Hvad er forskellen mellem code review og penetrationstest?

Et code review læser kildeteksten og finder fejl, før de leveres. En penetrationstest angriber den kørende applikation udefra. Begge supplerer hinanden: Reviewet finder årsager, testen viser, hvad der faktisk kan udnyttes.

Finder et code review sårbarheder som PHP2Shell?

Nej. PHP2Shell sidder i PHP-fortolkeren, ikke i applikationskoden. Mod det hjælper kun en PHP-opdatering med genstart. Et review finder fejl i egen kode, f.eks. injection, manglende rettighedskontroller eller usikker deserialisering.

Er PHPStan eller Psalm nok til et sikkerhedsreview?

De er et godt grundlag og finder mange fejl automatisk. Logikfejl, manglende rettighedskontroller og forkerte antagelser om forløb opdager dog kun et menneske, der ved, hvad applikationen skal gøre.

Hvor længe varer et sikkerhedskodereview?

Det afhænger af omfanget. Et review af hver ændring i pull requesten koster lidt tid. Et fuldstændigt review af et gammelt projekt er et projekt for sig, som man efter risiko afgrænser til de vigtigste dele.

Kilder

Akut kontakt

Hver time tæller. Skriv til os nu.

Beskriv kort system, PHP-version og observation. Vi vender tilbage, afklarer situationen og arbejder på afstand, indtil hændelsen er afsluttet og dokumenteret.

Akut hjælp