Insecure Direct Object References (IDOR) blijft een van de meest voorkomende kwetsbaarheden in e-commerce extensies. Het treedt op wanneer een website een unieke database-sleutel gebruikt om een actie uit te voeren, zonder te controleren of de gebruiker wel het recht heeft om die actie te starten. Een specifiek risico binnen WooCommerce bevindt zich in de logica rondom het annuleren van bestellingen via de frontend.

Hoe het IDOR-lek bij annuleringen werkt

WooCommerce biedt klanten de mogelijkheid om een bestelling die de status "Wachtend op betaling" heeft, handmatig te annuleren via hun dashboard. Dit gebeurt meestal via een specifieke URL die een bestellings-ID en een nonce bevat.

Als een ontwikkelaar echter een aangepaste plug-in bouwt (bijvoorbeeld een plug-in voor een klantenservice-portaal of een geavanceerd orderbeheer-systeem) en een AJAX-endpoint aanmaakt om bestellingen te annuleren zonder de eigendomsrechten te valideren, ontstaat het lek:

PHP
 
add_action('wp_ajax_cancel_custom_order', 'cancel_order_callback');

function cancel_order_callback() {
    $order_id = intval($_POST['order_id']);
    $order = wc_get_order($order_id);
    
    if ($order) {
        // ONVEILIG: Controleert NIET of de ingelogde gebruiker de eigenaar is!
        $order->update_status('cancelled', 'Geannuleerd via klantportaal.');
        wp_send_json_success();
    }
}

Een kwaadwillende klant kan een geautomatiseerd script opzetten dat POST-verzoeken naar dit endpoint stuurt en systematisch de order_id ophoogt van 1 tot 10000. Hierdoor kan hij in theorie alle actieve bestellingen van uw volledige webshop in één klap annuleren, wat leidt tot enorme logistieke en financiële schade.

Hoe ontwikkelaars dit lek voorkomen

Elke actie die de status van een object in de database wijzigt, moet gepaard gaan met een strikte controle van de huidige gebruikersrechten:

PHP
 
function cancel_order_callback() {
    check_ajax_referer('cancel_order_nonce', 'security');

    $order_id = intval($_POST['order_id']);
    $order = wc_get_order($order_id);
    $current_user_id = get_current_user_id();

    if ($order) {
        // VEILIG: Controleer of de klant de eigenaar is OF dat het een administrator is
        if ($order->get_customer_id() === $current_user_id || current_user_can('manage_woocommerce')) {
            $order->update_status('cancelled', 'Veilig geannuleerd.');
            wp_send_json_success();
        } else {
            wp_send_json_error('Toegang geweigerd.', 403);
        }
    }
}

Wat kan een webshopeigenaar doen?

  • Gebruik uitsluitend de core-annuleringslogica: Vertrouw op de ingebouwde mechanismen van WooCommerce voor het beheer van de orderstatus. Wees uiterst kritisch op plug-ins die beweren de koperomgeving te optimaliseren door eigen knoppen voor statuswijzigingen toe te voegen.