Actuele situatie: PHP2Shell. Twee kritieke PHP-kwetsbaarheden (CVSS 9.2) maken schadelijke code zonder inloggen mogelijk. Patches sinds 21-10-2026.Wat u nu moet doen →

Beveiligings-code-review voor PHP-projecten

Hoe teams de eigen PHP-code gericht doorlichten op beveiligingslekken: soorten reviews, kritieke functies, zinvolle hulpmiddelen en een checklist.

Stand 5 min. leestijdVeilig ontwikkelen

Kort gezegd: Een beveiligings-code-review voor PHP is het gerichte lezen van broncode met één vraag: waar kan vreemde invoer iets doen wat ze niet mag? Beproefd zijn twee vormen, een review van elke wijziging en een basisreview van het hele project, ondersteund door statische analyse met PHPStan of Psalm. Kwetsbaarheden in de PHP-interpreter zoals PHP2Shell vindt een review niet, wel de vele fouten die in de eigen code ontstaan.

Waarom juist nu naar de eigen code kijken?

PHP2Shell heeft in de laatste week van oktober 2026 vooral beheerders bezig gehouden. Patchen, herstarten, aantonen: het werk lag bij de server. Voor ontwikkelteams blijft daarna een ongemakkelijke vraag. Als een aanvaller via een andere kwetsbaarheid code kan uitvoeren, wat vindt hij dan in onze applicatie? En hoeveel van die kwetsbaarheden hebben wij zelf geschreven?

De OWASP Top 10 laat al jaren zien dat de meeste zwakke plekken in webapplicaties niet exotisch zijn. Ontbrekende toegangscontrole, injectie en onveilige configuratie staan ver bovenaan. Dat zijn fouten die een geoefend oog in de broncode vindt, lang voordat een aanvaller ze uitprobeert.

Daar komt een praktische reden bij. Veel bedrijven laten hun servers nu toch al controleren, patchen en harden. Wie de eigen applicatie in één moeite doorlicht, dicht de kloof tussen beheer en ontwikkeling. Een gehard server met een kwetsbare applicatie blijft aanvalbaar, en een netjes geschreven applicatie op niet-gepatchte PHP evenzeer.

Basisreview of wijzigingsreview?

De OWASP Cheat Sheet over secure code review onderscheidt twee soorten die elkaar in de praktijk aanvullen:

Soort Wanneer Omvang Doel
Basisreview (baseline) nieuw project, grote release, na een incident heel project, naar risico gewogen bestand aan zwakke plekken vastleggen
Wijzigingsreview (diff) elke pull request alleen gewijzigde code nieuwe fouten voorkomen

Een basisreview na een incident is bijzonder waardevol. Wie net een server heeft opgeschoond, moet weten of de applicatie nog meer toegangspunten biedt. Het wijzigingsreview houdt de stand daarna schoon, omdat elke wijziging vóór het samenvoegen ook vanuit beveiligingsoogpunt wordt gelezen.

Code-review in PHP: waar beveiligingsfouten zich ophopen

In PHP-projecten loont een gerichte blik op bepaalde functies en patronen. Ze zijn niet verboden, maar elke vindplaats verdient de vraag of vreemde gegevens erin kunnen komen.

Patroon in de code Mogelijk risico Verdieping
SQL via stringsamenvoeging met variabelen SQL-injectie SQL-injectie in PHP voorkomen
unserialize() op gegevens van buiten objectinjectie Onveilige deserialisatie in PHP
include of require met variabel pad insluiten van vreemde bestanden Local en remote file inclusion voorkomen
exec(), system(), shell_exec(), proc_open() uitvoering van opdrachten command injection
Uitvoer zonder htmlspecialchars() cross-site scripting contextgerichte escaping
== bij tokens of hashes typeomzetting omzeilt controles hash_equals(), strikte vergelijkingen
eval(), extract() op invoer code- of variabeleninjectie meestal zonder vervanging schrappen

Een snel eerste overzicht lukt met een eenvoudige zoekopdracht. Ze vervangt geen review, maar toont waar men moet beginnen:

# Vindplaatsen van riskante functies in de eigen code (vendor uitgesloten)
grep -rnE "\b(unserialize|eval|extract|shell_exec|exec|system|passthru|proc_open)\s*\(" src/ app/ 2>/dev/null

Minstens even belangrijk is wat in de code ontbreekt. Controleert elke controller of de aangemelde gebruiker precies dit gegevensrecord mag zien of wijzigen? Worden uploads beperkt op type en opslaglocatie? Zulke lacunes vindt geen zoekopdracht naar functienamen, alleen het lezen van het proces.

Hulpmiddelen die de review dragen

Statische analyse controleert code zonder haar uit te voeren. PHPStan en Psalm vinden typefouten, onbereikbare code en verkeerde aannames over retourwaarden. Psalm biedt bovendien een taint-analyse, die nagaat of gegevens uit verzoeken ongecontroleerd naar kritieke plekken stromen. Beide zijn stapsgewijs aan te scherpen, zodat ook oudere projecten kunnen instappen. Een overzicht geeft Statische analyse: PHPStan en Psalm.

# Statische analyse in het project, niveau stapsgewijs verhogen
vendor/bin/phpstan analyse src --level=5
# Taint-analyse met Psalm
vendor/bin/psalm --taint-analysis

Hulpmiddelen leveren aanwijzingen, geen oordelen. Elke treffer vraagt een beoordeling en een leeg rapport betekent niet dat de applicatie veilig is.

Even belangrijk als vinden is vastleggen. Elke bevinding moet met vindplaats, korte beschrijving, risico-inschatting, aanbevolen oplossing en status worden vastgelegd, het best rechtstreeks in het ticketsysteem van het team. Zo is na te gaan wat is verholpen, wat bewust is geaccepteerd en wat nog openstaat. Na de oplossing loont een tweede blik: is de oorzaak weggenomen of alleen dat ene symptoom? Duikt hetzelfde patroon op andere plekken in de code op? Een fout die eenmaal is gemaakt, zit volgens de ervaring zelden maar op één plek.

Een checklist voor het eigen team

Voor wijzigingsreviews heeft een korte, vaste lijst zich bewezen. Ze hoort in het sjabloon voor pull requests:

  1. Waar komen alle gegevens vandaan die deze wijziging verwerkt en worden ze aan de serverkant gecontroleerd?
  2. Worden databasequery's uitsluitend met plaatshouders gebouwd?
  3. Is elke uitvoer geëscaped voor zijn context, dus HTML, attribuut, JavaScript of URL?
  4. Controleert de code de machtiging voor precies dit object, niet alleen de aanmelding?
  5. Komen wachtwoorden, tokens of persoonsgegevens in logboeken of foutmeldingen terecht?
  6. Staan geheimen in de code of in versiebeheerde bestanden?
  7. Zijn nieuwe afhankelijkheden opgenomen en worden die onderhouden?
Tip

Laat beveiligingskritieke onderdelen zoals aanmelding, rechtenbeheer, betaalprocessen en uploads altijd door een tweede persoon lezen die niet aan de code heeft meegewerkt. De vreemde blik vindt aannames die de auteur vanzelfsprekend vindt.

Hoe helpt PHP SOS concreet?

  • Wij voeren met gespecialiseerde partners een basisreview van uw PHP-applicatie uit, gewogen naar de onderdelen met het hoogste risico.
  • Wij richten PHPStan of Psalm in passend bij de stand van uw project en schrijven de checklist voor uw pull requests.
  • Wij combineren de review met een blik op server en configuratie, want veel kwetsbaarheden ontstaan pas in het samenspel.
  • Waar een controle van buitenaf gewenst is, vullen wij de review aan met beveiligingsaudit en penetratietest.

Conclusie: Een code-review is de goedkoopste plek om beveiligingsfouten te verhelpen, namelijk voordat ze worden uitgeleverd. Wie elke wijziging met een korte lijst controleert en het project af en toe volledig doorlicht, verkleint het aanvalsoppervlak blijvend.

Veelgestelde vragen

Wat is het verschil tussen code-review en penetratietest?

Een code-review leest de broncode en vindt fouten voordat ze worden uitgeleverd. Een penetratietest valt de draaiende applicatie van buitenaf aan. Beide vullen elkaar aan: de review vindt oorzaken, de test toont wat werkelijk te misbruiken is.

Vindt een code-review kwetsbaarheden zoals PHP2Shell?

Nee. PHP2Shell zit in de PHP-interpreter, niet in de applicatiecode. Daartegen helpt alleen een PHP-update met herstart. Een review vindt fouten in de eigen code, zoals injectie, ontbrekende autorisatiecontroles of onveilige deserialisatie.

Zijn PHPStan of Psalm genoeg voor een beveiligingsreview?

Ze zijn een goede basis en vinden veel fouten automatisch. Logische fouten, ontbrekende autorisatiecontroles en verkeerde aannames over processen herkent echter alleen een mens die weet wat de applicatie moet doen.

Hoe lang duurt een beveiligings-code-review?

Dat hangt af van de omvang. Een review van elke wijziging in de pull request kost weinig tijd. Een volledige review van een gegroeid project is een eigen project, dat men op basis van risico tot de belangrijkste onderdelen beperkt.

Bronnen

Direct contact

Elk uur telt. Schrijf ons nu.

Beschrijf kort het systeem, de PHP-versie en wat u opmerkt. Wij nemen contact op, brengen de situatie in kaart en werken op afstand tot het incident is afgerond en gedocumenteerd.

Directe hulp