Webbeveiliging

SQL-injectie

Definitie

SQL-injectie is een aanval waarbij stukjes SQL worden meegestuurd in gegevens die naar een site gaan, zodat de query die de site naar zijn database stuurt een andere betekenis krijgt. Zo kan een aanvaller gegevens lezen, wijzigen of verwijderen, en soms een inlogcontrole omzeilen.

SQL-injectie, Webbeveiliging

Bijna alle dynamische sites, WordPress inbegrepen, bewaren hun inhoud in een database die met SQL wordt bevraagd. Als de code een query bouwt door er rechtstreeks een waarde van de bezoeker in te plakken, vermengt hij twee dingen die gescheiden horen te blijven: instructies en gegevens. De aanvaller maakt daar gebruik van door instructies te schrijven waar gegevens hadden moeten staan. MITRE registreert deze zwakte als CWE-89.

Hoe een SQL-injectie werkt

Neem code die een artikel op naam zoekt en de query met de hand in elkaar zet:

$sql = "SELECT * FROM artikelen WHERE naam = '" . $_GET['naam'] . "'";

Stuurt de bezoeker x' OR 'a'='a, dan sluit het aanhalingsteken de tekenreeks af die de ontwikkelaar had bedoeld, en wordt de rest SQL. De voorwaarde is altijd waar: de database geeft de hele tabel terug. Met andere payloads kan de aanvaller gegevens uit andere tabellen halen, ze wijzigen of verwijderen.

Vergelijking tussen een aan elkaar geplakte SQL-query, waarin de invoer x' OR 'a'='a de voorwaarde altijd waar maakt en de hele tabel teruggeeft, en een prepared statement in WordPress, waarin de invoer een gewone waarde blijft
Een prepared statement houdt de SQL-code en de waarden gescheiden: de invoer kan de betekenis van de query niet meer veranderen.

Wat een aanvaller ermee kan bereiken

OWASP vat de mogelijke gevolgen van een geslaagde injectie samen:

  • gevoelige gegevens lezen: e-mailadressen, bestellingen, wachtwoordhashes;
  • records toevoegen, wijzigen of verwijderen, bijvoorbeeld een account de rol Beheerder geven, wat er een vorm van privilege-escalatie van maakt;
  • een inlogcontrole omzeilen;
  • in sommige gevallen bestanden op de server lezen of opdrachten naar het systeem sturen, tot en met remote code execution.

Niet elke injectie toont het resultaat op het scherm. Bij de zogenaamde blinde varianten leidt de aanvaller de gegevens een voor een af uit verschillen in het antwoord of uit vertragingen. Dat gaat trager, maar met een automatisch hulpmiddel net zo effectief. Tussen de lekken die sinds 2020 in WooCommerce zijn gevonden zitten meerdere SQL-injecties, en de waarschuwing over All-in-One WP Migration laat zien dat zo'n lek al wordt afgetast zodra het bekend wordt.

Video: “Wat is een SQL‑injectie? Boolean attacks stap voor stap | Fundament” (Uitgeverij Instruct)

Voor WordPress: $wpdb->prepare()

De functies op hoog niveau (WP_Query, get_posts(), update_option()...) bouwen hun queries zelf. Zodra een plugin een eigen query schrijft met het object $wpdb, moet elke variabele waarde door $wpdb->prepare(). De placeholders zijn %s (tekenreeks), %d (geheel getal), %f (decimaal getal) en, sinds WordPress 6.2, %i voor de naam van een tabel of kolom.

$ids = $wpdb->get_col( $wpdb->prepare(
    "SELECT ID FROM {$wpdb->posts} WHERE post_author = %d AND post_status = %s",
    $auteur_id,
    'publish'
) );
  • Zet geen aanhalingstekens rond %s: de functie voegt ze zelf toe.
  • Geef bij een zoekopdracht met LIKE de volledige tekenreeks als argument mee, nadat je hem met $wpdb->esc_like() hebt behandeld.
  • ID's omzetten met absint() voordat je ze gebruikt is een extra zekerheid, geen vervanging van het prepared statement.

Hoe je je als eigenaar beschermt

  • Installeer beveiligingsupdates van plugins snel: hun code repareer je niet zelf.
  • Geef de databasegebruiker alleen de rechten die WordPress nodig heeft, zodat een gekaapte query minder schade aanricht.
  • Zet een web application firewall voor de site: de regels herkennen de bekendste injectie-payloads en kunnen een lek afdekken tot de patch er is.

WP Masquerade detecteert en blokkeert geen SQL-injecties: het is geen web application firewall. Door WordPress te verbergen wordt het lastiger om te zien welke plugins geïnstalleerd zijn, wat sommige bots hindert, maar dat vervangt nooit de update van de kwetsbare plugin.

Veelgemaakte fouten

  • "Met de hand" escapen met addslashes() of het vervangen van tekens, in plaats van een prepared statement te gebruiken.
  • De waarden wel voorbereiden, maar een kolomnaam of sorteervolgorde uit het verzoek ongewijzigd invoegen: gebruik %i of een whitelist.
  • Denken dat gegevens die veilig in de database staan overal veilig zijn: bij de weergave moet je met escaping cross-site scripting voorkomen.

Verder lezen

  • Artikel Alle kwetsbaarheden in WooCommerce sinds 2020: exploits en patches
  • Artikel All-in-One WP Migration: lek CVE-2026-19949 afgetast, patch 7.110

Bronnen

  1. OWASP: SQL Injection (externe link, opent in een nieuw tabblad)
  2. MITRE CWE-89: Improper Neutralization of Special Elements used in an SQL Command (SQL Injection) (externe link, opent in een nieuw tabblad)
  3. WordPress Developer Resources: wpdb::prepare() (externe link, opent in een nieuw tabblad)

Alle definities

WordPress-beveiliging, zonder ruis

Eén e-mail wanneer het ertoe doet: nieuw waargenomen aanvallen, updates van de plugin en praktische gidsen. Geen spam, afmelden met één klik.

Begin gratis, stap over op Pro wanneer je eraan toe bent

De gratis versie verbergt WordPress al en verplaatst de inlogpagina. Pro voegt aliassen, tweestapsverificatie en bewaking toe.