SQL Injection in mobiele ontwikkeling: wat het is, aanvalsmethoden en bescherming

Auteur: IT Sectr Gepubliceerd: 2026-04-06 Leestijd: 9 min

SQL Injection — een type aanval op de database van een applicatie waarbij een aanvaller schadelijke SQL-code in queryparameters injecteert en ongeautoriseerde toegang tot gegevens of de mogelijkheid om deze te wijzigen verkrijgt. Volgens gegevens van OWASP (2025) blijft SQL Injection een van de kritieke kwetsbaarheden die kan leiden tot volledige compromittering van de database. Injectie van SQL-code stelt de aanvaller in staat om records te lezen, te wijzigen en te verwijderen, en in sommige gevallen — toegang te krijgen tot het besturingssysteem van de server.

Belangrijkste punten

  • SQL Injection — het injecteren van SQL-code via gebruikersparameters, waardoor de logica van de databasequery verandert
  • Parametrisatie van queries — de belangrijkste beschermingsmethode: het scheiden van SQL-code van gegevens met prepared statements
  • Aanvalstypen — klassieke injectie (via WHERE), Blind SQLi (logische conclusies), UNION-based (lezen van andere tabellen)
  • Error-based SQLi — het extraheren van gegevens via foutmeldingen van de database
  • ORM-frameworks — verminderen het risico op SQLi bij correct gebruik, maar elimineren het niet volledig

Wat is SQL Injection?

SQL Injection is een kwetsbaarheid die ontstaat wanneer een applicatie een SQL-query opbouwt door stringconcatenatie met gebruikersgegevens. De aanvaller stuurt een speciaal geconstrueerde string naar de queryparameter die de structuur van het SQL-commando verandert. In plaats van gegevens te zijn, wordt de ingevoerde string onderdeel van de SQL-code, waardoor de aanvaller willekeurige query's op de database kan uitvoeren. Volgens het Verizon Data Breach Report (2025) komt SQL Injection voor in 8% van alle onderzochte datalekken.

Waarom is SQL Injection nog steeds actueel?

Ondanks de bekendheid van de kwetsbaarheid (eerste vermeldingen — eind jaren 1990) komt SQL Injection nog steeds voor in moderne applicaties. De oorzaak is menselijke factor: ontwikkelaars staan stringconcatenatie in code toe, legacy-code wordt niet gerefactord en ORM-frameworks worden onjuist gebruikt (bijvoorbeeld raw-queries met het substitueren van waarden via strings). Volgens Veracode (2026) bevat ongeveer 14% van alle gescande applicaties ten minste één SQLi-kwetsbaarheid.

Wat kan een aanvaller doen?

Een succesvolle SQL Injection geeft de aanvaller een breed scala aan mogelijkheden: het lezen van elke tabel in de database, inclusief wachtwoordhashes en persoonlijke gebruikersgegevens; het wijzigen en verwijderen van records; het uitvoeren van administratieve bewerkingen (DROP TABLE, TRUNCATE); in sommige configuraties — het extern uitvoeren van opdrachten via xp_cmdshell (MSSQL) of INTO OUTFILE (MySQL). De gevolgen variëren van het lekken van gebruikersgegevens tot volledig verlies van controle over het systeem.

Soorten SQL-injecties

SQL-injecties worden geclassificeerd op basis van de manier waarop gegevens uit de database worden geëxtraheerd. De keuze van de methode hangt af van hoe de applicatie queryresultaten en foutmeldingen verwerkt. OWASP-classificatie onderscheidt drie hoofdtypen: In-band (gegevens worden via hetzelfde kanaal geëxtraheerd), Inferential/Blind (logische conclusies) en Out-of-band (gegevens worden via een ander kanaal verzonden).

TypeMethode van gegevensextractieComplexiteitFrequentie
In-band (klassiek)Direct via het queryresultaatLaagHoog
Blind SQLiLogische conclusies op basis van serverantwoordenHoogGemiddeld
Out-of-bandVia een extern kanaal (DNS, HTTP)GemiddeldLaag

In-band SQL Injection (klassiek)

Het meest voorkomende type. De aanvaller injecteert SQL-code in de queryparameter en het resultaat van de injectie is direct zichtbaar in het serverantwoord. Twee subtypes: Error-based (via foutmeldingen van de database) en UNION-based (via de UNION SELECT-operator). Error-based gebruikt informatie uit foutmeldingen, bijvoorbeeld een MySQL-syntaxisfout die de tabelnaam of querystructuur kan onthullen. UNION-based maakt het mogelijk om resultaten van een legitieme query te combineren met gegevens uit andere databasetabellen.

Blind SQL Injection (blind)

Wordt gebruikt wanneer de applicatie geen queryresultaten of foutmeldingen weergeeft. De aanvaller stelt „ja/nee”-vragen door queries met logische voorwaarden te sturen en het verschil in serverantwoord te analyseren (bijvoorbeeld responstijd of pagina-inhoud). Time-based Blind SQLi gebruikt een vertragingsfunctie (SLEEP, WAITFOR DELAY) om voorwaarden te bevestigen — als de pagina langer laadt, is de voorwaarde waar. Deze methode is erg traag — het extraheren van één record kan uren duren.

python
# Voorbeeld Blind SQL Injection (time-based)
# Als SQLi kwetsbaar is, wordt SLEEP(2) onder voorwaarde uitgevoerd
import requests
import time

payload = "' OR IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a',SLEEP(2),0) -- "
url = "http://example.com/user?id=1" + payload

start = time.time()
response = requests.get(url)
elapsed = time.time() - start

# Als het antwoord na >2 seconden kwam — de eerste letter van het wachtwoord is 'a'
print(f"Time: {elapsed:.2f}s - First letter is 'a'" if elapsed > 2 else "First letter is not 'a'")

Out-of-band SQL Injection

Gegevens worden niet via het HTTP-antwoord verzonden, maar via alternatieve kanalen: DNS-query's, HTTP-verzoeken naar een externe server, SMTP. Wordt gebruikt wanneer de applicatie geen queryresultaten retourneert en geen fouten toont. MySQL ondersteunt de functie LOAD_FILE(), die een DNS-query kan initiëren, en MSSQL — xp_dirtree voor het verzenden van gegevens naar een externe SMB-server. Out-of-band SQL Injection is effectief, maar vereist extra configuratie op de server van de aanvaller en de aanwezigheid van bepaalde databasefuncties.

Hoe werkt SQL-injectie?

Het mechanisme van SQL Injection is gebaseerd op het feit dat SQL aanhalingstekens voor stringliterals gebruikt. Als de applicatie gebruikersinvoer direct in de SQL-query substitueert zonder escaping, kan de aanvaller de string „sluiten” en willekeurige SQL-code toevoegen. Bijvoorbeeld in de query SELECT * FROM users WHERE name = '$input' verandert substitutie van ' OR '1'='1 de query in SELECT * FROM users WHERE name = '' OR '1'='1', wat alle gebruikers retourneert.

Klassiek voorbeeld: omzeilen van authenticatie

Beschouw een loginformulier met de query SELECT * FROM users WHERE username = '$user' AND password = '$pass'. Als de aanvaller in het veld username admin' -- invoert en het wachtwoord leeg laat, wordt de resulterende query SELECT * FROM users WHERE username = 'admin' -- ' AND password = ''. De tekens -- commentariëren de rest van de query en de voorwaarde voor wachtwoordcontrole wordt uitgeschakeld. De server retourneert het record van gebruiker admin en de aanvaller logt in zonder het wachtwoord te kennen.

python
# Voorbeeld SQL Injection — omzeilen van authenticatie
# KWETSBAAR CODE: directe stringconcatenatie
def login_vulnerable(username, password):
    query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
    cursor.execute(query)
    return cursor.fetchone() is not None

# username = "admin' --" maakt wachtwoordcontrole ongedaan
# VEILIGE VERSIE: geparametriseerde query
def login_secure(username, password):
    query = "SELECT * FROM users WHERE username = %s AND password = %s"
    cursor.execute(query, (username, password))
    return cursor.fetchone() is not None

UNION-based: lezen van andere tabellen

De operator UNION SELECT maakt het mogelijk om de resultaten van twee SELECT-query's te combineren. Als de aanvaller een kwetsbare parameter vindt, voegt hij UNION SELECT toe met een query uit een andere tabel. Bijvoorbeeld: ' UNION SELECT username, password FROM admins --. Voorwaarde voor succes — het aantal kolommen in beide queries moet overeenkomen. Het aantal kolommen wordt bepaald via ORDER BY (substitutie van ' ORDER BY 1--, vervolgens 2, 3... tot een fout). Als de aanvaller het aantal kolommen kent, substitueert hij UNION SELECT met hetzelfde aantal velden.

SQL Injection in mobiele applicaties

Mobiele applicaties krijgen te maken met SQL Injection zowel aan de serverzijde (API) als aan de clientzijde — in lokale databases (SQLite, Realm). Hoewel het risico van server-SQLi in mobiele API vergelijkbaar is met webapplicaties, creëert lokale database een extra vector. Als de applicatie gegevens opslaat in SQLite en queries uitvoert met stringconcatenatie, kunnen schadelijke gegevens die via de API in de lokale database terechtkomen, bij latere verwerking SQLi veroorzaken.

SQL Injection in SQLite op Android/iOS

De lokale SQLite-database op het apparaat is ook kwetsbaar voor SQL Injection als de applicatie queries vormt door stringconcatenatie. Content Providers op Android en Core Data op iOS gebruiken standaard parametrisatie, maar raw-queries vereisen aandacht van de ontwikkelaar. SQLite ondersteunt geen meerdere queries via puntkomma, wat de mogelijkheden van de aanvaller beperkt, maar niet beschermt tegen het lezen van gegevens via WHERE-voorwaarden. Gebruik altijd selectionArgs in Android en NSPredicate met parameters in iOS.

SQL Injection via de API van een mobiele applicatie

De API waarmee de mobiele applicatie communiceert is even kwetsbaar als elke webserver. Mobiele ontwikkelaars denken vaak dat SQLi alleen een backend-probleem is, maar de kwetsbaarheid ontstaat op het niveau van het API-endpoint dat parameters van de client ontvangt. Verdeling van verantwoordelijkheid beschermt niet: als de backend-ontwikkelaar vergeten is de query te parametriseren, wordt de mobiele applicatie van de gebruiker een aanvalsvector. Eis van de backend het gebruik van ORM of prepared statements.

kotlin
// Voorbeeld SQL Injection in lokale SQLite op Android
// KWETSBAAR CODE: directe concatenatie
fun getUserVulnerable(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = $userId", null
    )
}

// VEILIGE VERSIE: parametrisatie via selectionArgs
fun getUserSecure(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = ?",
        arrayOf(userId)
    )
}

Methoden om SQL-injecties te voorkomen

Bescherming tegen SQL Injection is gebaseerd op een eenvoudig principe: vertrouw nooit op gebruikersinvoer in SQL-queries. De enige betrouwbare methode — parametrisatie van queries (prepared statements), waarbij SQL-code en gegevens apart worden verzonden. Alle andere methoden — escaping, validatie, WAF — zijn extra beschermingslagen, maar vervangen parametrisatie niet. Volgens OWASP (2025) voorkomt parametrisatie 100% van SQL Injection-aanvallen.

Prepared Statements (geparametriseerde queries)

Bij gebruik van prepared statements wordt de SQL-query eerst zonder gegevens door de databaseserver gecompileerd en vervolgens worden de parameterwaarden apart verzonden. De database behandelt parameters als gegevens, niet als uitvoerbare code. Zelfs als de aanvaller ' OR '1'='1 verzendt, interpreteert de database dit als een stringwaarde, niet als SQL-code. Prepared statements worden ondersteund door alle moderne talen en frameworks: PDO in PHP, PreparedStatement in Java, cursor.execute in Python.

ORM-frameworks en Query Builders

Moderne ORM's (Hibernate, Entity Framework, SQLAlchemy, Room) gebruiken automatisch parametrisatie bij het uitvoeren van queries, tenzij de ontwikkelaar overstapt op raw-queries. ORM biedt echter geen volledige bescherming: constructies zoals @Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true) in JPA vereisen het doorgeven van parameters via benoemde parameters, niet via concatenatie. Query Builders (Knex, jOOQ) parametriseren queries ook standaard, tenzij raw-methoden worden gebruikt.

String-escaping (niet aanbevolen als primaire methode)

Escaping van speciale tekens (mysql_real_escape_string) — een verouderde methode die niet beschermt tegen alle soorten SQL Injection. Probleem: escaping is afhankelijk van de codering en kan worden omzeild met multi-byte coderingen (bijv. GBK in Aziatische systemen). Gebruik escaping alleen in legacy-code waar parametrisatie niet mogelijk is, en altijd in combinatie met strikte validatie van het type invoergegevens.

MethodeEffectiviteitAanbeveling
Prepared Statements100%Verplicht voor alle queries
ORM (correct gebruik)99%Aanbevolen
String-escaping70% (afhankelijk van codering)Alleen legacy
Invoervalidatie (whitelist)50% (alleen voor getallen)Aanvullend
WAF (Web Application Firewall)60%Aanvullend

Principe van minimale rechten voor de database

Het account van de applicatie moet minimaal noodzakelijke rechten hebben: SELECT, INSERT, UPDATE, DELETE — alleen op tabellen die de applicatie echt nodig heeft. Verbied het gebruik van DROP, TRUNCATE, CREATE voor het applicatieaccount. Dit beperkt de schade, zelfs bij een succesvolle SQL Injection: de aanvaller kan geen tabellen verwijderen of administratieve bewerkingen uitvoeren.

Hulpmiddelen voor het detecteren van SQL-injecties

Regelmatig testen op SQL Injection zou deel moeten uitmaken van de pijplijn voor veilige ontwikkeling. Een combinatie van statische analyse, dynamische scanning en handmatige pentest geeft de beste resultaten. Volgens Synopsys Cybersecurity Report (2025) vinden automatische scanners tot 70% van SQLi-kwetsbaarheden, maar complexe Blind-aanvallen vereisen handmatig testen.

  • sqlmap — het populairste hulpmiddel voor automatische detectie en exploitatie van SQL Injection
  • OWASP ZAP — gratis DAST-scanner met modules voor actieve SQLi-scanning
  • Burp Suite Scanner — professioneel hulpmiddel met automatische detectie van SQL Injection
  • SonarQube — statische code-analyse op kwetsbaarheden, inclusief SQLi-patronen
  • CodeQL — semantische code-analyse voor het vinden van SQL-injecties in broncode

Voor mobiele applicaties is ook analyse van lokale SQLite belangrijk: controleer alle rawQuery-aanroepen, ContentProvider-queries en Room-queries met rawQuery. Hulpmiddelen: Android Studio Lint (detecteert SQLi in SQLite), MobSF (Mobile Security Framework) voor automatische statische en dynamische analyse van APK/IPA. Het wordt ook aanbevolen om API-endpoints te testen via sqlmap met proxy-interceptie van mobiel applicatieverkeer.

Veelgestelde vragen

Wat is het verschil tussen SQL Injection en NoSQL Injection?

SQL Injection valt relationele databases aan via SQL-queries. NoSQL Injection tast niet-relationele databases (MongoDB, Couchbase) aan via hun query-operators ($gte, $ne, $where). In MongoDB is injectie mogelijk als de applicatie een BSON-document uit een JSON-string vormt. Beschermingsmechanismen zijn vergelijkbaar: parametrisatie en typevalidatie.

Hoe kan ik SQL Injection zelf in code detecteren?

Vind alle plaatsen waar SQL-queries worden gevormd door stringconcatenatie met gebruikersgegevens. Zoek naar patronen zoals "SELECT ... WHERE id = " + userId of f"UPDATE ... SET name = '{name}'". Elke dergelijke string is een potentiële SQL-injectie. Vervang ze allemaal door geparametriseerde queries of prepared statements.

Beschermt ORM automatisch tegen SQL Injection?

ORM-frameworks beschermen alleen automatisch als u hun Query Builder-methoden en benoemde parameters gebruikt. Als u raw-queries gebruikt (nativeQuery in JPA, rawQuery in Room), werkt de bescherming niet — u moet parameters doorgeven via prepared expressions, niet via stringconcatenatie.

Wat is Second-Order SQL Injection?

Second-Order SQL Injection is een aanval waarbij schadelijke gegevens als veilig in de database worden opgeslagen maar vervolgens in een andere query zonder escaping worden gebruikt. Bijvoorbeeld, een aanvaller registreert zich met username ' OR '1'='1. De gegevens worden opgeslagen als string — bij registratie is er geen aanval. Maar als een andere query de username in SQL substitueert zonder parametrisatie, wordt de injectie geactiveerd.

Kan NoSQL Injection gevaarlijker zijn dan SQL Injection?

NoSQL Injection is potentieel gevaarlijker vanwege mindere bewustwording bij ontwikkelaars. Ontwikkelaars weten van SQL Injection en de meeste gebruiken ORM, maar weinig mensen weten van NoSQL Injection. In MongoDB kan een onjuist gevormde query alle documenten van de collectie retourneren. Bescherming — dezelfde prepared statements (BSON-parametrisatie) en strikte validatie van invoergegevens.

Samenvatting

  • SQL Injection — aanval door injectie van SQL-code via niet-geescape gebruikersparameters in databasequery's
  • Belangrijkste typen — In-band (klassiek), Blind (blind, op tijd gebaseerd), Out-of-band (via extern kanaal)
  • Parametrisatie van queries — de enige 100% betrouwbare beschermingsmethode tegen SQL Injection
  • Mythe over ORM — ORM beschermt alleen bij gebruik van ingebouwde methoden, raw-queries met concatenatie blijven kwetsbaar
  • Principe van minimale rechten — beperking van databaserechten minimaliseert schade bij een succesvolle aanval
  • Regelmatig testen — sqlmap, OWASP ZAP, SonarQube moeten deel uitmaken van de CI/CD-pijplijn
  • Lokale SQLite — mobiele applicaties moeten ook queries naar de lokale database parametriseren

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook