WooCommerce biedt standaard een aantal orderstatussen, zoals "Wachtend na betaling", "Verwerking" en "Afgerond". Veel webshopeigenaren maken gebruik van plug-ins van derden om aangepaste orderstatussen toe te voegen (bijv. "Ingepakt", "Verzonden naar extern magazijn" of "Wachten op leverancier"). Omdat deze statussen vaak dynamisch worden gefilterd en opgeroepen in het dashboard, kan een slechte codering in deze extensies leiden tot een kritieke SQL-injectie kwetsbaarheid.
Hoe het SQLi-lek ontstaat in orderstatussen
Wanneer een beheerder in het dashboard klikt op een specifieke orderstatus om alle bijbehorende bestellingen te bekijken, stuurt de browser een GET-verzoek met de naam van de status mee: https://uwshop.nl/wp-admin/admin.php?page=wc-orders&status=custom-packed
Als de ontwikkelaar van de plug-in een op maat gemaakte database-query heeft geschreven om de orders te tellen of op te halen, en de parameter status direct in de SQL-instructie plakt, ontstaat het lek:
$status = $_GET['status'];
// ONVEILIG: Directe concatenatie in SQL
$order_count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status = '" . $status . "'");
Een aanvaller met toegang tot een shopmanager-account (of via een CSRF-aanval op een ingelogde administrator) kan de URL aanpassen naar: ?page=wc-orders&status=custom-packed' UNION SELECT user_pass FROM wp_users --
De database zal de query uitvoeren en de gevoelige wachtwoordhashes van de administrators op het scherm tonen, gecamoufleerd binnen de statistieken van de orderpagina.
Hoe ontwikkelaars dit lek voorkomen
Ontwikkelaars moeten er altijd naar streven om gebruik te maken van de ingebouwde WooCommerce CRUD-API (zoals wc_get_orders()) in plaats van handmatige SQL-queries op de wp_posts of de nieuwe High-Performance Order Storage (HPOS) tabellen. wc_get_orders() behandelt parameters inherent veilig.
Als een handmatige query via $wpdb onvermijdelijk is, moet de parameter altijd via $wpdb->prepare() worden gesaniseerd:
$status = sanitize_key($_GET['status']); // Zorg dat de invoer alleen veilige tekens bevat
$query = $wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status = %s",
$status
);
$order_count = $wpdb->get_var($query);
Praktisch advies voor site-eigenaren
-
Activeer HPOS: WooCommerce heeft High-Performance Order Storage (HPOS) geïntroduceerd. Dit systeem verhuist orders van de generieke
wp_poststabel naar specifieke e-commerce tabellen. Dit verbetert niet alleen de snelheid, maar minimaliseert ook de impact van traditionele WordPress post-queries exploits. -
Gebruik code-audit tools: Als u een plug-in voor aangepaste orderstatussen installeert, scan deze dan vooraf met een tool zoals Plugin Check (geleverd door de WordPress-community) om basale codeerfouten op te sporen.
