# Beveiligings-code-review voor PHP-projecten

> Beveiligings-code-review voor PHP: baseline of diff, riskante functies, hulpmiddelen zoals PHPStan en Psalm en een checklist voor het eigen team.

Bron: https://phpsos.de/nl/blog/sicherheits-code-review-php/  
Stand: 25-10-2026  
Aanbieder: PHP SOS, PHP-noodhulp en serverbeveiliging. Directe hulp via WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wij%20hebben%20hulp%20nodig%20met%20onze%20PHP-server.%20Bedrijf%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**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](https://phpsos.de/nl/ratgeber/sql-injection-php/) |
| `unserialize()` op gegevens van buiten | objectinjectie | [Onveilige deserialisatie in PHP](https://phpsos.de/nl/ratgeber/deserialisierung-php/) |
| `include` of `require` met variabel pad | insluiten van vreemde bestanden | [Local en remote file inclusion voorkomen](https://phpsos.de/nl/ratgeber/lfi-rfi/) |
| `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:

```bash
# 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](https://phpsos.de/nl/php/statische-analyse/).

```bash
# 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](https://phpsos.de/nl/leistungen/sicherheitsaudit-penetrationstest/).

**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

- [OWASP: Secure Code Review Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secure_Code_Review_Cheat_Sheet.html)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [PHPStan](https://phpstan.org/)
