PHP Object Injection, veroorzaakt door onveilige deserialisatie, is een van de meest complexe kwetsbaarheden binnen het PHP- en WordPress-landschap. Hoewel het minder vaak voorkomt dan XSS of SQL-injectie, is de impact vrijwel altijd maximaal: een succesvolle aanval leidt in de regel tot Remote Code Execution (RCE), waarmee een hacker de volledige controle krijgt over de server waarop de WooCommerce-webshop draait. Deze kwetsbaarheid ontstaat wanneer gebruikersinvoer rechtstreeks wordt doorgegeven aan de PHP-functie unserialize().
Wat is serialisatie en deserialisatie?
In PHP is serialisatie het proces waarbij een complex data-object (zoals een array) wordt omgezet in een stringindeling. Dit is handig om de data op te slaan in een database. Deserialisatie is het omgekeerde proces: de string wordt weer omgezet naar het oorspronkelijke PHP-object.
In PHP ziet een geserialiseerde array er bijvoorbeeld zo uit: a:2:{i:0;s:5:"appel";i:1;s:6:"banaan";}. WordPress maakt zelf op grote schaal gebruik van serialisatie in de tabel wp_options. WordPress regelt dit intern via de functies maybe_serialize() and maybe_unserialize(), wat over het algemeen veilig gebeurt omdat de data uit een vertrouwde bron (de database) komt.
Het gevaar van PHP Object Injection
Het probleem ontstaat wanneer een plug-in data van de gebruiker (bijvoorbeeld uit een cookie) rechtstreeks decodeert met unserialize().
Als een aanvaller een speciaal geconstrueerde string aanlevert die een object representeert van een klasse die aanwezig is in de actieve code van de website, kan hij misbruik maken van zogenaamde magic methods in PHP. Magic methods zijn ingebouwde functies binnen PHP-klassen die automatisch worden getriggerd bij bepaalde gebeurtenissen, zoals __wakeup() (wanneer een object wordt gedeserialiseerd) of __destruct() (wanneer een object wordt vernietigd).
Als er in de code van WordPress of een actieve plug-in een klasse bestaat met een __destruct() methode die een bestand verwijdert of code uitvoert op basis van een interne variabele, kan de aanvaller die variabele via de geserialiseerde string manipuleren. Dit concept staat bekend als een Property Injection of een POP Chain.
Een praktijkvoorbeeld in WooCommerce-extensies
In het verleden zijn er ernstige kwetsbaarheden ontdekt in WooCommerce-gerelateerde plug-ins (zoals add-ons voor verzendtarieven) die klantgegevens opsloegen in een cookie in geserialiseerd formaat. Een aanvaller kon zijn eigen winkelwagencookie aanpassen, er een kwaadaardig PHP-object in injecteren, de pagina verversen en de server dwingen een webshell (kwaadaardig script) aan te maken in de hoofdmap van de website. Vanaf dat moment had de hacker permanente toegang tot de serveromgeving.
Hoe ontwikkelaars PHP Object Injection kunnen voorkomen
De absolute best practice voor ontwikkelaars is simpel: Gebruik nooit unserialize() op data die afkomstig is van de client.
Als het noodzakelijk is om complexe datastructuren uit te wisselen tussen de client en de server, gebruik dan JSON in plaats de PHP serialisatie.
-
Gebruik
json_encode()om data om te zetten naar een string. -
Gebruik
json_decode()om de data weer te decoderen.
JSON is puur een data-indeling. Het kan geen PHP-klassen of objecten representeren, waardoor het onmogelijk is om via JSON-decodering magic methods te triggeren of code uit te voeren.
// ONVEILIG
$user_data = unserialize( $_COOKIE['custom_plugin_data'] );
// VEILIG
$user_data = json_decode( $_COOKIE['custom_plugin_data'], true );
Wat kunnen webshopeigenaren doen?
Omdat dit een puur infrastructurele kwetsbaarheid is, bent u als sitebeheerder afhankelijk van goede preventie:
-
PHP-versie up-to-date houden: Modernere PHP-versies (PHP 8.x) hebben verbeteringen doorgevoerd in de manier waarop met serialisatie wordt omgegaan.
-
Kwalitatieve plug-ins kiezen: Kies voor plug-ins van gerenommeerde ontwikkelaars die regelmatig updates uitbrengen.
-
Beveiligingsmonitoring: Zorg dat u direct meldingen ontvangt wanneer er kritieke kwetsbaarheden (RCE) worden gemeld in plug-ins die u actief gebruikt, zodat u deze direct kunt updaten.
