SQL Injection Uitgelegd voor Beginners

SQL injection is een van de oudste en meest voorkomende kwetsbaarheden in webapplicaties. Al meer dan twintig jaar staat het in de top van beveiligingsrisico's, en toch worden er nog steeds websites mee gehackt. In dit artikel leggen we stap voor stap uit wat SQL injection is, hoe het werkt, waarom het zo gevaarlijk is, en - het allerbelangrijkste - hoe je je ertegen beschermt.

Wat is SQL?

Voordat we het over SQL injection hebben, moet je eerst begrijpen wat SQL is. SQL staat voor Structured Query Language en is de standaardtaal waarmee websites met hun database communiceren.

Denk aan een database als een enorm digitaal archief met tabellen vol informatie: gebruikersnamen, wachtwoorden, e-mailadressen, bestellingen, berichten - eigenlijk alles wat een website opslaat. SQL is de taal waarmee je die informatie opvraagt.

Een simpel voorbeeld: als je inlogt op een website, wordt er achter de schermen zoiets uitgevoerd:

SELECT * FROM gebruikers
WHERE naam = 'jan' AND wachtwoord = 'geheim123';

Dit vraagt aan de database: "Geef me alle gegevens van de gebruiker met de naam 'jan' en het wachtwoord 'geheim123'." Als die combinatie bestaat, mag je inloggen. Zo niet, krijg je een foutmelding.

SQL wordt uitgesproken als "ess-kjoe-el" of "sequel". Bijna elke website ter wereld gebruikt een vorm van SQL - van je favoriete webshop tot je bank en sociale media.

Wat is SQL Injection?

SQL injection (vaak afgekort als SQLi) is een aanvalstechniek waarbij een aanvaller kwaadaardige SQL-code "injecteert" via een invoerveld op een website. In plaats van een normale gebruikersnaam of wachtwoord, typt de aanvaller een stukje SQL-code dat de database-query verandert.

Het probleem ontstaat wanneer een website gebruikersinvoer direct in een SQL-query plakt zonder deze te controleren of te beveiligen. De database kan dan niet onderscheiden wat "echte" SQL is en wat door de gebruiker is ingevoerd. Het behandelt alles als geldige instructies.

Hoe Werkt SQL Injection? Een Praktijkvoorbeeld

Laten we het concreet maken met een klassiek voorbeeld: het omzeilen van een loginpagina.

De Normale Situatie

Stel, een website heeft een inlogformulier. De code achter dat formulier bouwt een SQL-query als volgt op:

SELECT * FROM gebruikers
WHERE naam = '[INVOER_NAAM]' AND wachtwoord = '[INVOER_WACHTWOORD]';

Als je normaal inlogt met naam jan en wachtwoord geheim123, wordt dit:

SELECT * FROM gebruikers
WHERE naam = 'jan' AND wachtwoord = 'geheim123';

Prima. Maar wat als iemand iets anders invult?

De Aanval

Een aanvaller typt het volgende als gebruikersnaam:

' OR '1'='1

De query wordt dan:

SELECT * FROM gebruikers
WHERE naam = '' OR '1'='1' AND wachtwoord = '';

Wat ziet de database nu? De conditie '1'='1' is altijd waar. De database geeft daarom alle gebruikers terug. De aanvaller is nu ingelogd - vaak als de eerste gebruiker in de tabel, wat meestal de administrator is.

Dit voorbeeld is vereenvoudigd voor educatieve doeleinden. In de praktijk zijn moderne loginpagina's beter beveiligd. Probeer dit nooit op echte websites - dat is illegaal en strafbaar! Gebruik altijd een testomgeving of de HackSimulator.

Wat kan een aanvaller nog meer doen?

SQL injection gaat veel verder dan inloggen. Met de juiste query kan een aanvaller:

  • Data uitlezen - Alle gebruikersnamen, wachtwoorden, e-mailadressen en persoonlijke gegevens opvragen
  • Data wijzigen - Wachtwoorden resetten, rechten verhogen, content aanpassen
  • Data verwijderen - Hele tabellen leegmaken met DROP TABLE
  • Het besturingssysteem bereiken - In sommige gevallen kan een aanvaller via de database opdrachten uitvoeren op de server zelf

Een ander gevaarlijk voorbeeld is het gebruik van UNION SELECT om data uit andere tabellen te lezen:

' UNION SELECT naam, wachtwoord FROM beheerders --

De -- aan het einde is een SQL-commentaar dat de rest van de originele query negeert. Hiermee kan een aanvaller gevoelige informatie uit willekeurige tabellen opvragen.

Soorten SQL Injection

Niet alle SQL injection-aanvallen werken hetzelfde. Security professionals onderscheiden drie hoofdcategorieen:

1. In-Band SQLi (Klassiek)

Dit is de meest directe vorm. De aanvaller stuurt een kwaadaardige query en ziet het resultaat direct op de webpagina. Het voorbeeld hierboven met ' OR '1'='1 is een typisch in-band voorbeeld. De twee meest voorkomende varianten zijn Error-based (foutmeldingen bevatten database-informatie) en UNION-based (de aanvaller combineert zijn eigen query met de originele).

2. Blind SQLi

Bij blind SQL injection ziet de aanvaller het resultaat niet direct op de pagina. In plaats daarvan stelt hij ja/nee-vragen aan de database en leidt het antwoord af uit hoe de website reageert. Laadt de pagina normaal? Dan was het antwoord "ja". Krijg je een fout? Dan was het "nee".

Dit is langzamer maar werkt ook als de website geen foutmeldingen toont. Een variant hiervan is time-based blind SQLi, waarbij de aanvaller de database vraagt om een pauze in te lassen (bijv. SLEEP(5)). Als de pagina vijf seconden langer laadt, was het antwoord "ja".

3. Out-of-Band SQLi

De zeldzaamste vorm. Hierbij stuurt de database de gestolen data naar een externe server van de aanvaller, bijvoorbeeld via een DNS-verzoek. Dit werkt alleen als de databaseserver uitgaande verbindingen mag maken, wat in goed beveiligde omgevingen geblokkeerd is.

Als beginner focus je het beste eerst op in-band SQLi. Dat is het makkelijkst te begrijpen en te detecteren. Blind en out-of-band SQLi zijn voor gevorderde toepassingen.

De Impact: Waarom SQL Injection zo Gevaarlijk is

SQL injection is niet zomaar een theoretisch probleem. Enkele van de grootste datalekken in de geschiedenis zijn veroorzaakt door SQL injection:

  • Heartland Payment Systems (2008) - 134 miljoen creditcardnummers gestolen via SQLi. Schade: meer dan 200 miljoen dollar.
  • Sony PlayStation Network (2011) - Gegevens van 77 miljoen accounts gelekt. Het netwerk lag wekenlang plat.
  • Yahoo (2012) - 450.000 gebruikersnamen en wachtwoorden gelekt via een eenvoudige UNION-based SQL injection.
  • TalkTalk (2015) - Een 15-jarige hacker stal gegevens van 157.000 klanten. Boete: 400.000 pond.
SQL injection staat al sinds de allereerste editie in de OWASP Top 10 - de lijst van de tien meest kritieke beveiligingsrisico's voor webapplicaties. Sinds 2021 valt het onder de bredere categorie "Injection", die op plaats 3 staat. Dat het na twintig jaar nog steeds in de top staat, zegt genoeg over hoe wijdverspreid het probleem is.

SQLmap: Automatische Detectie

SQLmap is een van de meest gebruikte tools door ethisch hackers om SQL injection-kwetsbaarheden automatisch op te sporen en te testen. In plaats van handmatig query's te proberen, doet sqlmap dit voor je - met tientallen technieken tegelijk.

Zo gebruik je sqlmap om een URL te testen op SQL injection:

$ sqlmap -u "http://test.example.com/page?id=1" --dbs
[*] Starting sqlmap v1.7... [*] Testing connection to target URL [*] Testing for SQL injection on parameter 'id' Parameter: id (GET) Type: boolean-based blind Payload: id=1 AND 1=1 Type: UNION query Payload: id=1 UNION ALL SELECT NULL,NULL,table_name FROM information_schema.tables [*] Available databases: [*] information_schema [*] webshop_db [*] users_db [!] Let op: sqlmap is een offensive tool. Gebruik ALLEEN op systemen met toestemming!

In dit voorbeeld test sqlmap de parameter id in de URL. De tool probeert automatisch tientallen SQL injection-technieken en meldt welke werken. De --dbs flag vraagt om een lijst van alle databases op de server.

Je kunt sqlmap veilig uitproberen in de HackSimulator. Daar leer je de basiscommando's en -opties zonder risico. Zo snap je hoe een ethisch hacker SQL injection detecteert voordat je ooit een echt systeem aanraakt.

Andere handige sqlmap-opties:

$ sqlmap -u "http://target.com/page?id=1" --tables
[*] Fetching tables for database: webshop_db +----------------+ | klanten | | bestellingen | | producten | | beheerders | +----------------+
$ sqlmap -u "http://target.com/page?id=1" -T beheerders --dump
[*] Fetching entries for table 'beheerders' +----+----------+------------------+ | id | naam | wachtwoord_hash | +----+----------+------------------+ | 1 | admin | 5f4dcc3b5aa7... | | 2 | moderator| 482c811da5d5... | +----+----------+------------------+ [TIP] Gehashte wachtwoorden gevonden. Gebruik 'hashcat' om de sterkte te testen.

Hoe Bescherm je je Tegen SQL Injection?

Nu je weet hoe SQL injection werkt, is de volgende vraag: hoe voorkom je het? Gelukkig zijn er bewezen technieken die SQL injection vrijwel volledig elimineren.

1. Prepared Statements (Parameterized Queries)

Dit is de gouden standaard en verreweg de belangrijkste maatregel. Prepared statements scheiden de SQL-code van de gebruikersinvoer. De database weet dan precies wat "code" is en wat "data" is.

Onveilige code (kwetsbaar):

-- ONVEILIG: invoer wordt direct in de query geplakt
query = "SELECT * FROM users WHERE name = '" + invoer + "'";

Veilige code (met prepared statement):

-- VEILIG: de ? is een placeholder voor data
query = "SELECT * FROM users WHERE name = ?";
execute(query, [invoer]);

Bij de veilige variant wordt de invoer van de gebruiker nooit als SQL-code geinterpreteerd. Als iemand ' OR '1'='1 invoert, zoekt de database letterlijk naar een gebruiker met die naam - en vindt er geen.

Prepared statements zijn beschikbaar in elke moderne programmeertaal en elk database-framework. In PHP gebruik je PDO, in Python gebruik je parameterized queries met psycopg2 of SQLAlchemy, en in Java gebruik je PreparedStatement. Er is geen excuus om ze niet te gebruiken.

2. Input Validatie

Controleer altijd wat een gebruiker invoert voordat je het verwerkt:

  • Type-checking - Verwacht je een getal? Controleer of het ook echt een getal is.
  • Whitelisting - Sta alleen bekende, veilige waardes toe (bijv. alleen letters en cijfers voor een gebruikersnaam).
  • Lengte-limieten - Een gebruikersnaam van 500 tekens is verdacht.
  • Speciale tekens escapen - Verwerk aanhalingstekens en andere SQL-gevoelige karakters zodat ze hun speciale betekenis verliezen.
Input validatie is een goede extra laag, maar vertrouw er niet op als enige bescherming. Prepared statements zijn je eerste verdedigingslinie. Input validatie is je tweede. Gebruik altijd beide.

3. Web Application Firewall (WAF)

Een WAF is een beveiligingslaag die al het verkeer naar je website filtert. Een WAF herkent bekende SQL injection-patronen (zoals ' OR '1'='1) en blokkeert deze voordat ze je applicatie bereiken.

Bekende WAF-oplossingen zijn Cloudflare, AWS WAF en ModSecurity. Een WAF is echter geen vervanging voor veilige code - het is een extra beschermingslaag. Slimme aanvallers kunnen WAF-filters soms omzeilen met obfuscation-technieken.

4. Least Privilege Principe

Geef de database-gebruiker die je website gebruikt zo min mogelijk rechten. Als je website alleen gegevens hoeft te lezen, geef dan alleen leesrechten. Als een aanvaller er toch doorheen komt, kan hij dan in ieder geval geen data verwijderen of de hele server overnemen.

5. Error Handling

Toon nooit gedetailleerde database-foutmeldingen aan gebruikers. Een foutmelding als "MySQL error: column 'password' not found in table 'users'" geeft een aanvaller gratis informatie over je database-structuur. Toon in productie alleen generieke foutmeldingen en log de details intern.

De beste bescherming is een combinatie van al deze maatregelen. Security professionals noemen dit defense in depth: meerdere lagen beveiliging zodat als een laag faalt, de volgende het opvangt.

Ethische Overwegingen

SQL injection testen is een belangrijk onderdeel van ethisch hacken en pentesting. Maar er zijn strikte regels:

  • Altijd toestemming - Test alleen op systemen waar je schriftelijke toestemming voor hebt. Geen uitzonderingen.
  • Scope respecteren - Als je toestemming hebt voor de webshop, test dan niet ook de mailserver.
  • Data beschermen - Vind je gevoelige gegevens? Bewaar ze niet en deel ze niet. Meld het aan de opdrachtgever.
  • Verantwoord rapporteren - Documenteer je bevindingen duidelijk zodat het ontwikkelteam de kwetsbaarheden kan oplossen.
SQL injection uitvoeren op een website zonder toestemming is een misdrijf onder artikel 138ab van het Wetboek van Strafrecht (Computervredebreuk). De straffen kunnen oplopen tot vier jaar gevangenisstraf. Dit geldt ook als je "alleen maar wilt kijken" of "het bedrijf wilt helpen". Zonder toestemming is het illegaal, punt.

Wil je op een verantwoorde manier oefenen? Er zijn speciale platforms die hiervoor gebouwd zijn:

  • DVWA (Damn Vulnerable Web Application) - Een bewust kwetsbare webapplicatie om op te oefenen
  • WebGoat - OWASP's educatieve platform voor web security
  • HackTheBox / TryHackMe - Online labs met legale hackuitdagingen
  • HackSimulator.nl - Oefen sqlmap en andere tools veilig in je browser

Oefenen in HackSimulator.nl

Probeer sqlmap zelf!

In de HackSimulator kun je veilig experimenteren met sqlmap en andere security tools. Leer hoe een ethisch hacker SQL injection detecteert, welke opties belangrijk zijn, en hoe je je bevindingen rapporteert - allemaal zonder risico.

Open de simulator

Samenvatting

SQL injection is een aanvalstechniek waarbij kwaadaardige SQL-code via invoervelden wordt geinjecteerd om een database te manipuleren. Het is al decennialang een van de meest voorkomende en gevaarlijkste kwetsbaarheden op het web. De kern van het probleem is simpel: gebruikersinvoer wordt als code behandeld in plaats van als data.

De oplossing is net zo simpel: gebruik prepared statements. Combineer dit met input validatie, een WAF, het least privilege principe en goede error handling, en je hebt een robuuste verdediging opgebouwd.

Als ethisch hacker is het je taak om deze kwetsbaarheden te vinden voordat criminelen dat doen. Tools als sqlmap maken dat proces efficient, maar vergeet nooit: alleen testen met toestemming, altijd verantwoord rapporteren, en nooit data misbruiken.

Meer lezen?