Serialiseren betekent gestructureerde gegevens (een array, een object) omzetten in tekst om ze op te slaan of te versturen; deserialiseren is de omgekeerde bewerking. Het probleem ontstaat wanneer de gegevens die weer worden opgebouwd van buitenaf komen: een cookie, een formulierveld, een URL-parameter. MITRE deelt deze zwakte in onder CWE-502, "deserialisatie van onbetrouwbare gegevens"; in PHP spreekt men ook van PHP object injection.
Hoe de aanval werkt in PHP
Een geserialiseerde PHP-string beschrijft zelf het type van wat erin zit. Zo staat O:4:"User":1:{s:4:"name";s:3:"Bob";} voor een object van de klasse User met een eigenschap name. Een aanvaller die deze string in handen heeft, kan unserialize() dus een object laten maken van elke klasse die de site heeft geladen, met de waarden die hij wil.
Dat object wordt gevaarlijk door de magische methoden die PHP automatisch aanroept: __wakeup() bij het opbouwen, __destruct() bij het opruimen, __toString() wanneer het object als tekst wordt gebruikt. Door klassen te combineren die al in de code van de site staan en elkaars methoden aanroepen, bouwt de aanvaller een gadget chain (POP-chain) die eindigt in een gevaarlijke actie: een bestand verwijderen, een PHP-bestand schrijven, remote code execution.

Een WordPress-voorbeeld: GiveWP
Het lek CVE-2024-5932 in de donatieplugin GiveWP, tot en met versie 3.14.1, liet een niet-geauthenticeerde aanvaller een PHP-object injecteren via de parameter give_title. Een gadget chain in de plugin leidde tot het uitvoeren van code en het verwijderen van bestanden; de gepubliceerde CVSS 3.1-score is 10. Ons artikel over PHP object injection gaat uitgebreid in op dit geval en het mechanisme.
Ook eenmaal binnen gebruiken aanvallers deserialisatie: de backdoor die in 2025 werd toegevoegd aan de pluginportfolio van EssentialPlugin draaide op unserialize, zoals ons artikel over supply-chain-aanvallen beschrijft.
Voor WordPress: unserialize en maybe_unserialize
WordPress slaat veel geserialiseerde gegevens op, vooral in de optietabel en de metadata. De functie maybe_unserialize() leest ze terug: als de gegevens eruitzien als geserialiseerde data (is_serialized()), roept ze unserialize() aan, zonder de toegestane klassen te beperken. Ze biedt dus geen enkele bescherming en mag nooit gegevens van een bezoeker krijgen.
- Wissel uit in JSON: de PHP-documentatie raadt
json_encode()enjson_decode()aan voor alle gegevens die via de gebruiker lopen. JSON maakt nooit objecten van willekeurige klassen aan. - Verwacht niet te veel van
allowed_classes: deze optie vanunserialize()beperkt welke klassen worden aangemaakt, maar de PHP-handleiding zegt dat je nooit onbetrouwbare gegevens aan deze functie moet doorgeven, ongeacht die waarde. - Onderteken wat heen en weer moet: als geserialiseerde gegevens echt via de browser moeten reizen, voorkomt een HMAC-handtekening die je vóór het lezen controleert dat iemand ze wijzigt.
- Houd PHP up-to-date: sinds PHP 8.0 worden de metadata van phar-archieven niet meer automatisch gedeserialiseerd, wat een aanvalsroute rond bestandsinclusie en wrappers heeft gesloten.
Als beheerder is het belangrijkste verweer de betrokken plugins bij te werken, want het lek zit in hun code. Een web application firewall kan in de tussentijd verdachte geserialiseerde strings blokkeren, en de waarschuwingen voor kwetsbare plugins van WP Masquerade Pro laten je weten wanneer een geïnstalleerde plugin bij de getroffen versies hoort. WP Masquerade filtert zelf geen verzoeken.