Rond 24 februari werd bekend dat de WordPress-plugin Ultimate Member kwetsbaar is. De kwetsbaarheid betreft een aanvalshoek door middel van SQL-injectie. De laatste update van deze plugin, versie 2.8.3, repareert deze kwetsbaarheid. Toch blijkt dat vele websites deze update nog niet hebben geïnstalleerd.
Wat is SQL-injectie?
SQL staat voor Structured Query Language. Dit is een term die bekend is in relatie tot databases, vooral webdatabases zoals MySQL of de variant daarvan genaamd MariaDB. SQL-injectie kan optreden als de softwareontwikkelaar niet voorzichtig is.
Kort gezegd komt het erop neer dat een database opdrachten uitvoert. Bijvoorbeeld om een voor- en achternaam op te slaan. Deze instructie bestaat natuurlijk uit de voor- en achternaam, maar ook het commando aan de database om deze op te slaan. Een database kan echter ook andere commando's uitvoeren, zoals het tonen of verwijderen van data.
SQL-injectie maakt gebruik van kennis over databasecommando's. Het manipuleert de gegevens zodanig dat het niet het bedoelde commando uitvoert, maar extra commando's toevoegt. Hierdoor kan een kwaadwillende gegevens ontfutselen, toevoegen of vernietigen.
SQL-injectie concreet toepassen
Voor programmeurs geef ik graag een concreet voorbeeld van SQL-injectie met behulp van PHP. Stel je het volgende database commando voor:
$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
Door de variabelen $username en/of $password te veranderen, kan SQL-injectie plaatsvinden. Stel $password is niet het correcte wachtwoord, maar als volgt:
' OR '1'='1
Door deze extra apostrof aan het begin kan de variabele worden onderbroken en kan de aanvaller het commando beïnvloeden. De query wordt dan:
SELECT * FROM users WHERE username='$username' AND password='' OR '1'='1'
Omdat '1' altijd gelijk is aan '1', zal deze query altijd waar zijn, ongeacht welk wachtwoord wordt ingevoerd. Hierdoor kan een aanvaller zonder geldige referenties inloggen op het systeem, omdat de query altijd een overeenkomst zal vinden.
SQL-injectie is uitstekend te voorkomen
Wat deze situatie opmerkelijk maakt, is dat SQL-injectie te voorkomen is. Sinds PHP versie 5.1.0 van 24 november 2005 is er de mogelijkheid om PDO in te zetten. PDO staat voor "PHP Data Objects". Met PDO kunnen zogenaamde "Prepared Statements" worden gebruikt. Dit voorkomt dat kwaadwillenden gegevens in databasequeries kunnen injecteren op een manier die schadelijk kan zijn.
Simpel gezegd kan in het vorige voorbeeld $password niet langer worden onderbroken om vervolgens het databasecommando aan te passen. Door prepared statements zal zelfs een extra apostrof nog altijd worden gezien als onderdeel van het wachtwoord.
Waarom komt SQL-injectie in 2024 nog voor?
SQL-injectie staat in 2024 nog steeds in de top 10 van meest voorkomende kwetsbaarheden volgens OWASP, ondanks de beschikbare oplossingen zoals PDO voor PHP. Dit heeft te maken met twee oorzaken. Ten eerste is er een grote groep onervaren en vaak goedkopere programmeurs.
Ten tweede is het gebruik van PDO niet verplicht, waardoor programmeurs nog steeds gegevens direct in de query kunnen opnemen. Dit kan veilig gebeuren, maar vereist wel expertise om te voorkomen dat invoer van willekeurige gebruikers of kwaadwillenden in kwetsbare queries terechtkomt.
Wat moet ik doen?
Als je de "Ultimate Member"-plugin voor WordPress gebruikt, is het aan te raden om te updaten naar versie 2.8.3 of hoger om de kwetsbaarheid te verhelpen. Daarnaast is het verstandig om te overwegen of het acceptabel is om een dergelijke plugin te blijven gebruiken. Zoals eerder besproken is SQL-injectie een bekend probleem waarvoor al tientallen jaren een oplossing beschikbaar is. Een dergelijk probleem mag in 2024 niet meer voorkomen als de ontwikkelaar over voldoende expertise beschikt.
Robuuste en veilige (maatwerk-)plugins voor WordPress is een kwestie van de de juiste partner vinden.