De snelle ontwikkeling van nieuwe technologieën heeft bedrijven niet alleen een concurrentievoordeel en een winststijging opgeleverd, maar ook flink wat hoofdbrekens bezorgd op het gebied van cybersecurity. Tegenwoordig kunnen hackers zowel handmatige als geautomatiseerde aanvallen uitvoeren, die dagelijks verfijnder worden. Het grappige is dat, hoewel de meest populaire softwarekwetsbaarheden bekend zijn en gemakkelijk te detecteren, ze nog steeds actief worden misbruikt.
Zo werd SQL-injectie voor het eerst ontdekt in 1998, maar het is nog steeds het nummer één beveiligingsrisico in webapplicaties, volgens OWASP. Bovendien zijn SQL-injecties, samen met brute force en het gebruik van gestolen inloggegevens, verantwoordelijk voor maar liefst 80% van de datalekken wereldwijd.
Gezien hoe wijdverbreid deze webkwetsbaarheid is, hebben we een uitgebreide gids samengesteld over SQL-injecties, met de volgende vragen:
In dit artikel behandelen we:
Wat is SQL-injectie?
Voordat we direct naar de definitie van SQL-injectie gaan, laten we het eerst hebben over SQL zelf. SQL (Structured Query Language) is een programmeertaal die wordt gebruikt om databases te benaderen en te manipuleren.
SQL wordt gebruikt door enkele van de populairste databasebeheersystemen, zoals MySQL en Microsoft SQL.
SQL-injectie (SQLi) is een cybersecurityaanval die websites en webapplicaties die SQL-databases gebruiken, target. Het is een code-injectietechniek die gebruikmaakt van kwaadaardige SQL-statements die via webinvoer worden ingevoerd. Met andere woorden, een bedreigingsacteur of de “slechterik” probeert een reeks SQL-commando’s om de database te manipuleren en een reactie te ontvangen die hopelijk gevoelige gegevens onthult.
In geval van een succesvolle SQL-injectie kan de hacker een van de volgende dingen doen:
- Authenticatie omzeilen
- De identiteit van een gebruiker stelen, inclusief een C-level executive
- Records in de database ophalen, toevoegen, wijzigen of volledig vernietigen
- Administrator worden
- Andere manipulatieve gedragingen uitvoeren
SQL-injecties zijn zo wijdverbreid vanwege de prevalentie van websites die SQL-databases gebruiken en de relatief eenvoudige implementatie.
populariteit van
gedeelde database-infrastructuur = meerdere apps tegelijk getroffen
Hoe werkt SQL-injectie?
SQL-injecties zijn mogelijk wanneer een website of webapplicatie geen correct proces voor input sanitization heeft. Simpel gezegd, input sanitization voorkomt dat hackers speciale tekens gebruiken om kwaadaardige code in het data-invoer veld te injecteren.
Een legitieme SQL-query is niets anders dan een interactie tussen de gebruiker en de database. Door bijvoorbeeld een gebruikersnaam en wachtwoord in te voeren, vraagt de gebruiker om toegang tot de software. Als enkele van de ingevoerde tekens niet overeenkomen met de inloggegevens die op de server zijn opgeslagen, wordt de toegang geweigerd.
Echter, als ontwikkelaars onzorgvuldig waren en geen sterke input sanitization hebben geïmplementeerd, kan de hacker invoervelden gebruiken om hun eigen verzoeken naar de database te sturen door strings van uitvoerbare SQL-code in te voeren.
Voordat we laten zien hoe je een SQL-injectie uitvoert, gaan we eerst de soorten SQL-injectie behandelen om de principes die deze webgebaseerde aanval mogelijk maken, beter te begrijpen.
Soorten SQL-injectie
Afhankelijk van de intentie van de bedreigingsacteur en de beveiligingsmaatregelen van het systeem, worden verschillende SQL-injectietechnieken toegepast. Laten we enkele van de meest voorkomende SQL-injectietypen doornemen om bewust te zijn van de scenario’s die hackers groen licht geven.
Klassieke SQL-injecties
De klassieke SQL-injectie, ook bekend als in-band, maakt gebruik van één communicatiekanaal om zowel de aanval uit te voeren als de gegevens te verzamelen. Het wordt beschouwd als de eenvoudigste te implementeren en kan gegevens exfiltreren via:
- Foutmeldingen. In dit geval voert de black hat opzettelijk invoer in die tot een fout leidt om inzicht te krijgen in de database structuur. We zijn er zeker van dat u die verwarrende foutmeldingen hebt gezien die geen waarde hebben voor eindgebruikers, maar wel cruciale technische details bevatten – precies wat hackers willen ophalen.
- UNION-operators. Hackers kunnen het UNION-sleutelwoord gebruiken om hun oorspronkelijke query uit te breiden door twee of meer SELECT-statements te combineren. Dit type aanval maakt cross-table queries mogelijk.
Blind SQL-injecties
Dit type injectie vereist meer geduld van de hacker, omdat er geen gegevens op de webpagina worden weergegeven en de database-opsomming karakter voor karakter gebeurt. Het is toepasbaar wanneer de database alleen generieke foutmeldingen toont, maar de code nog steeds kwetsbaar kan zijn. Blind SQL-injecties vereisen brute force-technieken en talloze verzoeken; dit proces kan echter ook worden geautomatiseerd dankzij tools zoals SQLMap. Blind SQL-injecties worden verder onderverdeeld in:
- Inhoud-gebaseerd. De bedreigingsagent stelt een reeks waar/niet waar-vragen en bepaalt of de stelling waar of onwaar was op basis van het verschil in de respons van de app.
- Tijd-gebaseerd. De hacker gebruikt verschillende tijdsgebaseerde functies van SQL-databases om te achterhalen welk type database wordt gebruikt, aangezien verschillende databases verschillende functies gebruiken voor dezelfde bewerkingen. Door ook sleep of soortgelijke SQL-commando’s te gebruiken, kunnen ze gemakkelijk identificeren of de query waar of onwaar is: onmiddellijke respons – onwaar; de database reageert met de genoemde vertraging – waar.
Out-of-Band SQL-injecties
Dit type SQL-injectie is minder gebruikelijk, omdat het afhankelijk is van het vermogen van de server om DNS- of HTTP-verzoeken te maken om gegevens naar de hacker te verzenden. Deze laatste functies zijn mogelijk niet op elke database-server van een app ingeschakeld, wat de succeskans van deze kwaadaardige onderneming beperkt.
Out-of-band SQL-injecties worden zo genoemd omdat de hacker niet hetzelfde kanaal kan gebruiken om een aanval uit te voeren. Wanneer de respons van de server bijvoorbeeld te traag of instabiel is, wordt het moeilijk om met inferentiële SQLi te werken.
kwetsbaarheid
wereldwijd
Voorbeeld van een SQL-injectieaanval
Hoewel het altijd een goed idee is om jezelf te voorzien van theoretische kennis, is het nog voordeliger om praktische expertise op te doen in de bestudeerde vraag.
Zonder verder oponthoud, laten we eens kijken naar de basisprincipes die u een beter begrip kunnen geven van hoe u een SQL-injectie kunt uitvoeren.
Voorbeelden van SQLi-code
SQLi-typen zijn inderdaad talrijk; de eenvoudigste en meest populaire draaien echter om manipulaties met de UPDATE-, INSERT- en SELECT-statements, evenals de WHERE- en ORDER BY-clausules.
De onderstaande voorbeelden behandelen de basisprincipes en zijn alleen mogelijk als er geen beveiligingsmaatregelen zijn tegen het plaatsen van gevaarlijke syntax in invoervelden.
Gegevens ophalen met WHERE-clausule
Stel dat u door een e-commerce site bladert en bij de sectie Accessoires bent gestopt. Een typische URL zou er in dit geval als volgt uitzien:
https://e-commerce-website.com/products?category=Accessories
Wat er onder de motorkap gebeurt, ziet er iets anders uit:
SELECT * FROM products WHERE category = 'Accessories' AND released = 1
Hier maakt de webapplicatie een SQL-query naar de database om alleen de beschikbare accessoires aan de eindgebruiker weer te geven. Dit verzoek kan eenvoudig worden gewijzigd door wat “slimme” SQL-syntax in te voegen, zoals dubbele streepjes om een deel van de query uit te commentariëren en het zo irrelevant te maken.
https://insecure-website.com/products?category=Accessories’––
Hier is de SQL-code voor dezelfde query:
SELECT * FROM products WHERE category = 'Accessories'--' AND released = 1
In dit geval kan de hacker ook alle niet-uitgebrachte items bekijken, aangezien de beperking released=1 is uitgeschakeld.
De kwetsbaarheid kan verder worden misbruikt door invoer toe te voegen die altijd waar is, zoals OR 1=1.
https://insecure-website.com/products?category=Accessories’+OR+1=1––
Wat de database ontvangt, is het volgende:
SELECT * FROM products WHERE category = 'Accessories' OR 1=1--' AND released = 1
In het bovenstaande geval zal de database alle items retourneren, zowel uitgebrachte als niet-uitgebrachte, uit alle andere categorieën.
Inloggen zonder inloggegevens
Een ander toepassingsgeval van slimme syntax is het verkrijgen van toegang tot een app met slechts een gebruikersnaam tot iemands beschikking. De strategie is hetzelfde: gebruik de dubbele streepjes-reeks om een deel van de code uit te grijven.
Hier is de basis SQL-code die de aanmelding van de gebruiker mogelijk maakt:
SELECT * FROM users WHERE username = 'john' AND password = 'johndoe123'
Hier is de geïnjecteerde versie van dezelfde query:
SELECT * FROM users WHERE username = 'administrator'--' AND password = ''
Als de hacker aanneemt dat de gebruikersnaam “administrator” of “admin” is, wat nog steeds het geval kan zijn, en de SQL-commentaarindicator gebruikt vóór het wachtwoorddeel van de query, kunnen ze inloggen als de daadwerkelijke beheerder of de gebruiker die toevallig deze gebruikersnaam had.
Wat nog schokkender is, is dat in sommige gevallen zelfs de gebruikersnaam niet eens vereist is.
SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""
Door de app te misleiden met altijd-ware uitspraken, zoals dat één lege string gelijk is aan een andere lege string, kan de hacker succesvol inloggen zonder enige inloggegevens.
Maximale winst behalen
Als een initiële SQLi succesvol was en de app reageert met de daadwerkelijke gegevens uit de getargete tabel, is dit een kans die hackers niet mogen missen. Hoogstwaarschijnlijk gaan ze door met een UNION-aanval.
Hackers kunnen de mogelijkheden van het UNION-sleutelwoord benutten, zoals het uitvoeren van een of meer aanvullende SELECT-queries en het toevoegen van de resultaten aan de oorspronkelijke query, om toegang te krijgen tot gegevens uit andere tabellen.
Een UNION-aanval vereist wel enige kennis van de databasestructuur en andere voorwaarden waaraan moet worden voldaan. Maar als we aannemen dat een bedreigingsacteur het aantal kolommen weet dat de oorspronkelijke query retourneert, het type gegevens dat ze kunnen bevatten, de naam van de tabel en de kolommen ervan, kunnen ze van dit
SELECT name, description FROM products WHERE category = 'Accessories'
naar dit
' UNION SELECT username, password FROM users--,
gaan, waardoor ze niet alleen de producten en hun beschrijvingen, maar ook de bijbehorende gebruikersnamen en wachtwoorden kunnen ophalen.
Voorbeelden van SQLi in de praktijk
Om te bewijzen dat we de werkelijke dreiging van SQLi niet overdrijven, hebben we een lijst samengesteld van vrij recente SQLi-aanvallen en de zware verliezen die de getroffen bedrijven hebben geleden of hadden kunnen lijden als er geen white hat hackers waren geweest.
3,7 miljoen gehashte wachtwoorden gelekt
Eenvoudige Google-hack om DB-kwetsbaarheden te vinden
U vraagt zich misschien ook af hoe hackers weten welke website (van de bijna 2 miljard) ze moeten targeten om hun kansen op een succesvolle SQLi-aanval te vergroten. Welnu, er bestaat een speciale techniek die bekend staat als Google hacking of Google dorking. Dit laatste wordt gebruikt voor het ophalen van allerlei gevoelige informatie – van e-mailadressen en betalingskaartgegevens tot kwetsbare servers en blootgestelde internetcamera’s.
Google hacking is ontstaan in 2002 toen Johnny Long, een erkende computerbeveiligingsexpert, besloot geavanceerde Google-zoekopdrachten te documenteren die kwetsbare systemen of gevoelige informatie blootlegden. In de loop der jaren is de oorspronkelijke lijst van Google Dorks, met andere woorden geavanceerde zoekreeksen, uitgegroeid tot een volledige database, die nu wordt onderhouden door Offensive Security.
Het gebruik van Google hacking voor het vinden van SQLi is slechts een klein onderdeel van wat u met deze geavanceerde zoektechniek kunt doen. En hier leest u hoe u dat kunt doen.
Laten we zeggen dat we naar Google gaan en iets als dit typen:
site:com inurl:id "You have an error in your SQL syntax"
Deze query vraagt de zoekmachine om alle .com-websites te doorzoeken die enige vorm van syntactische fouten in hun SQL-code hebben. Deze syntactische fouten zijn waarschijnlijk opzettelijk geplaatste injecties.
Nog een punt om in gedachten te houden is dat Google niet de enige engine is die geavanceerd zoeken ondersteunt. U kunt dezelfde resultaten bereiken met Bing, Yahoo of DuckDuckGo; het enige verschil zit in de syntaxis van de zoekoperator die enigszins verschilt per engine.
Hoe SQL-injectie te voorkomen?
Nadat u al deze beangstigende informatie over de gevaren van SQLi heeft geconsumeerd, is de redelijke vraag die in u opkomt hoe u SQL-injectie kunt voorkomen. Omdat deze aanval al een tijdje bestaat, hebben beveiligingsexperts geleerd hoe ze deze kunnen bestrijden en webapplicaties toekomstbestendig kunnen maken tegen verschillende SQLi-typen.
Hoewel elk geval uniek is en professioneel onderzoek vereist van beveiligingsconsultants en pentest-specialisten, zullen deze beveiligingsbest practices voor de meeste organisaties volstaan en het risico op SQLi aanzienlijk verminderen.
Hier zijn enkele van de bekende en effectieve technieken voor het voorkomen van SQL-injectie.
Refactoren van legacy code
Legacy software staat bekend om het veroorzaken van een reeks problemen, waarvan beveiliging een van de meest schadelijke is.
De reden waarom legacy apps de laaghangende vruchten zijn voor hackers, is hun onvermogen om efficiënte beveiligingsmaatregelen te integreren vanwege incompatibiliteit of andere technische beperkingen. Daarom, als de app niet volledig kan worden herschreven en gemigreerd naar de moderne technologiestack, moet ten minste gedeeltelijke refactoring van de meest kwetsbare modules worden overwogen.
Gebruik server-side inputvalidatie
Elke data-invoer vereist validatie om de gebruiker toegang te verlenen of andere acties uit te voeren. Client-side validatie wordt vaak beschouwd als een snelle initiële controle binnen de browser, waardoor de gebruiker snel fouten in de invoer kan opmerken. Of deze nu ingebouwd is in HTML5 of aangepast met Javascript, client-side validatie is gemakkelijk te omzeilen en wordt als onveilig en onbetrouwbaar beschouwd.
Daarom kan sterke inputvalidatie alleen server-side worden uitgevoerd. Bovendien is server-side inputvalidatie verder onderverdeeld in allowlist (positieve) en blocklist (negatieve) methoden. De eerste wordt als effectiever beschouwd bij het bestrijden van SQLi.
Dit is hoe allowlist server-side inputvalidatie werkt: de server accepteert alleen de gegevens die als goed en acceptabel zijn gedefinieerd. Het verifiëren van creditcardnummergegevens kan bijvoorbeeld stappen omvatten zoals het controleren op het verwachte aantal cijfers, alleen numerieke invoer en de Luhn-formule.
Bovendien moet server-side validatie zowel op syntactisch (correctheid van datum, valutatekens) als semantisch niveau (validatie van de invoer in relatie tot de bedrijfscontext) worden uitgevoerd.
Hoewel allowlisting vrij uitgebreid kan zijn, mag server-side inputvalidatie niet worden gezien als de primaire beveiligingsmaatregel tegen SQLi, maar eerder als een extra stap in een meerlaags beveiligingsprogramma.
Beperk de privileges van databasegebruikers
Het principe van minimale privileges (POLP) is bekend in het vakgebied van de informatietechnologie. En het is vrij eenvoudig: beperk de databasetoegang op basis van individuele gebruikersrollen en hun dagelijkse functies.
Meestal heeft slechts een beperkt aantal mensen de behoefte om iets in de database te maken of te verwijderen. Daarom is het cruciaal om ervoor te zorgen dat de meerderheid van de gebruikers alleen leesrechten en gedeeltelijke tabelweergaven heeft die strikt noodzakelijk zijn voor hun werkzaamheden.
Een andere belangrijke factor om rekening mee te houden is dat u de standaard DBMS-privileges moet wijzigen naar beperkt, iets wat de hacker geen volledige controle over het systeem zal geven, zelfs niet bij een succesvolle SQLi-aanval.
Bij meerdere applicaties die dezelfde database gebruiken, vereist elke applicatie een aparte databasegebruikersaccount met afzonderlijke toegangsrechten. Deze aanpak helpt ook de schade van potentiële SQLi’s te minimaliseren.
Al met al, om het sneeuwbaleffect te voorkomen waarbij de hacker rootrechten verkrijgt via SQLi, maakt u uw toegangsbeleid zo granulair mogelijk.
Gebruik prepared statements met geparametriseerde queries
Volgens OWASP is het gebruik van prepared statements met geparametriseerde queries de primaire verdediging tegen SQLi. Prepared statements zijn zo effectief tegen SQLi omdat ze het voor de database gemakkelijk maken om duidelijk onderscheid te maken tussen de code en de door de gebruiker aangeleverde invoer.
Een typisch prepared statement volgt een eenvoudig algoritme:
- een SQL-statement sjabloon wordt gemaakt en naar de database gestuurd
- de SQL-query doorloopt een parseer- en semantische controle
- de SQL-query wordt gecompileerd met placeholder-tekst (binding)
- de placeholders worden vervangen door de door de gebruiker aangeleverde invoer
- de query wordt in de cache opgeslagen
- de database voert het statement uit
Zoals uit deze stappen blijkt, kan de door de gebruiker verstrekte gegevens de intentie van een query niet beïnvloeden, omdat deze gescheiden is van de uitvoerbare code en altijd als een eenvoudige string zal worden geïnterpreteerd.
Hier rijst nog een vraag: als prepared statements zo veilig zijn, waarom hebben we dan nog steeds zoveel SQLi-incidenten? De kwestie is dat prepared statements in bepaalde gevallen een negatieve invloed kunnen hebben op de prestaties van de app, daarom kiezen ontwikkelaars ervoor om ze niet te gebruiken en terug te vallen op andere, minder effectieve beveiligingstechnieken.
Implementeer stored procedures op de juiste manier
Een stored procedure is een voorbereide SQL-code die kan worden opgeslagen en meerdere keren in de toekomst kan worden gebruikt. Het verschil tussen een stored procedure en een prepared statement is dat de SQL-code voor de eerste wordt gedefinieerd en opgeslagen in de database zelf: wanneer de query moet worden uitgevoerd, wordt deze gewoon aangeroepen vanuit de app.
Stored procedures worden als net zo effectief beschouwd als prepared statements, onder de voorwaarde dat ze veilig zijn geïmplementeerd. Anders zijn ze ook kwetsbaar voor SQLi.
Ontwikkelaars moeten voorzichtig zijn om geen onveilige dynamische SQL op te nemen in de stored procedure. Als het genereren van dynamische SQL binnen een stored procedure volkomen onvermijdelijk is, adviseren wij om de queries binnen de stored procedure te parameteriseren in plaats van de parameters te concatenëren.
Ontsnap aan alle door de gebruiker aangeleverde invoer
Deze aanpak is een nogal wanhopige remedie: deze mag alleen worden gebruikt als niets anders haalbaar is. Een typisch gebruiksscenario is het beveiligen van legacy software en het hebben van een beperkt budget voor volledige inputvalidatie.
Zo werkt escaping: de escape-functie codeert speciale tekens, zoals “/”, “?”, “$”, zodat de database de door de gebruiker aangeleverde invoer niet kan verwarren met code van de ontwikkelaar.
Hoewel elke DBMS zijn eigen escape-schema heeft, is het doel hetzelfde: voorkomen dat de door de gebruiker aangeleverde invoer wordt geïnterpreteerd als een uitvoerbaar commando.
Nogmaals, deze techniek kan geen 100% bescherming tegen SQLi garanderen. Idealiter moet de app van de grond af opnieuw worden geschreven met behulp van geparametriseerde queries of stored procedures.
Een andere escape-methode is het hex-coderen van alle door de gebruiker aangeleverde invoer. Dit scenario veronderstelt het coderen van niet alleen speciale tekens, maar elk teken in de invoer voordat deze in de SQL-query wordt opgenomen.
Verberg databasefouten
Wat de databasefout heeft veroorzaakt, is erg nuttig voor de ontwikkelaar, maar niet voor de eindgebruiker. Het is cruciaal om ervoor te zorgen dat foutmeldingen geen gevoelige informatie onthullen die een hacker zou kunnen gebruiken.
Geef bijvoorbeeld, in plaats van de SQL-instructie weer te geven die onthult waar de fout precies is opgetreden, algemene, klantgerichte pop-ups weer, zoals: “Sorry, we ondervinden technische problemen. Probeer het later opnieuw.”
Versleutel gevoelige gegevens
Het achterlaten van zeer vertrouwelijke gegevens in platte tekst is nooit een goed idee. Daarom hebben zoveel bedrijven, met name in de financiële technologiesector, gezondheidszorg en media, dataredundantie in hun systemen geïntegreerd – de kosten van gegevensblootstelling zijn simpelweg te hoog (gemiddeld ongeveer 4 miljoen dollar).
Een andere cruciale factor om rekening mee te houden is dat encryptie alleen geen wondermiddel is. Stel dat een bedrijf wachtwoord-hashing heeft, wat betekent dat de werkelijke wachtwoorden nooit worden opgeslagen, alleen hun gehashte equivalenten. Maar als gebruikers geen sterke wachtwoorden hebben aangemaakt, wat vaak het geval is, kunnen hun inloggegevens gemakkelijk worden gecompromitteerd met hash- of regenboogtabellen die sleutels aan waarden kunnen koppelen.
Het toevoegen van ‘salts’ aan de versleutelde hashes zou een extra beveiligingslaag bieden. Simpel gezegd, salting is wanneer een willekeurig stuk gegevens aan het wachtwoord wordt toegevoegd voordat het wordt gehasht. Gesalteerde wachtwoorden verminderen de kans dat zwakke gebruikerswachtwoorden worden gevonden in een hashtabel.
Voer regelmatig code-inspecties uit
SQLi is vaak het resultaat van slechte softwareontwikkelingspraktijken. Daarom is het redelijk om het preventieplan te starten bij de broncode door externe beveiligingsexperts een onbevooroordeelde code-audit te laten uitvoeren.
Even belangrijk is het uitvoeren van regelmatige penetratietests om rode vlaggen te signaleren en kwetsbaarheden te detecteren die door scanners en fuzzers over het hoofd worden gezien. Voor een bekwame pentest-specialist is het ontdekken van een SQLi-kwetsbaarheid een eenvoudige taak; bovendien kunnen zij de uitkomst van andere potentiële of bestaande exploits uitleggen en een plan voor SQL-injectieherstel aanbieden dat past bij de status quo van het bedrijf.
Samenvatting
SQL-injectie is een kwetsbaarheid die zo oud is dat het beschamend is te weten dat het nog steeds een bedreiging vormt voor moderne websites en apps. Het is wijdverbreid vanwege de relatief eenvoudige implementatie, de prevalentie van SQL DBMS’s en de immense waarde van bedrijfsgegevens. Het goede nieuws: het is te voorkomen. Het vergt alleen het afstemmen van uw technische inspanningen op de nieuwste beveiligingspraktijken, continue monitoring en inspectie, en onafhankelijke SQL-injectietests om resterende hiaten te dichten.
Wat is uw ervaring met het bestrijden van SQLi? We horen het graag; deel uw ervaringen via e-mail of in de reacties!
Voorbereid is half gewonnen: de ultieme
SQLi-preventiecheatsheet


