Sécurité

SQL-injectie voorkomen: de complete gids

SQL-injectie is een van de gevaarlijkste webkwetsbaarheden. Leer hoe u uw database beschermt met bewezen technieken.

18 mars 20263 min de lectureWarDek Team

Wat is SQL-injectie?

SQL-injectie (SQLi) is een aanvalstechniek waarbij kwaadaardige SQL-code wordt geïnjecteerd via gebruikersinvoer, waardoor een aanvaller ongeautoriseerde database-operaties kan uitvoeren. Ondanks dat het een van de oudste webkwetsbaarheden is (bekend sinds 1998), staat het nog steeds in de OWASP Top 10 en wordt het actief misbruikt.

De gevolgen zijn ernstig: volledige database-extractie, data-wijziging, authenticatie-bypass, en in sommige gevallen overname van de server.

Hoe SQL-injectie werkt

Het basisprincipe

Een kwetsbare applicatie bouwt SQL-queries op door gebruikersinvoer direct in de query-string te plakken:

-- Kwetsbare query (NOOIT doen)
SELECT * FROM users WHERE username = '" + userInput + "' AND passwd = '" + passInput + "'

Als een aanvaller als gebruikersnaam invoert: admin' --

Wordt de query:

SELECT * FROM users WHERE username = 'admin' --' AND passwd = ''

Het -- maakt de rest van de query tot commentaar. De aanvaller logt in als admin zonder wachtwoord.

Typen SQL-injectie

TypeMethodeDetectie
In-band (Classic)Resultaat direct zichtbaar in responseMakkelijk te detecteren
Error-basedDatabase-foutmeldingen onthullen informatieMakkelijk te detecteren
Union-basedUNION SELECT om data uit andere tabellen te lezenMakkelijk te detecteren
Blind (Boolean)Waar/onwaar vragen stellen via conditiesMoeilijker te detecteren
Time-based blindVertragingen in response metenMoeilijk te detecteren
Out-of-bandData via alternatief kanaal exfiltreren (DNS, HTTP)Zeer moeilijk te detecteren

De oplossing: parameterized queries

De primaire en meest effectieve bescherming tegen SQL-injectie is het gebruik van parameterized queries (ook bekend als prepared statements). Hierbij wordt de SQL-structuur gescheiden van de data.

Node.js (PostgreSQL)

// VEILIG — parameterized query
const result = await pool.query(
  'SELECT * FROM users WHERE email = $1 AND status = $2',
  [email, 'active']
);
// ONVEILIG — string concatenatie (NOOIT doen)
const result = await pool.query(
  `SELECT * FROM users WHERE email = '${email}'`
);

ORM's (Prisma, Drizzle)

ORM's gebruiken standaard parameterized queries:

// Prisma — automatisch veilig
const user = await prisma.user.findUnique({
  where: { email: userInput },
});

Let op: raw queries in ORM's omzeilen deze bescherming:

// ONVEILIG — raw query met string interpolatie
const result = await prisma.$queryRawUnsafe(
  `SELECT * FROM users WHERE name = '${userInput}'`
);

// VEILIG — raw query met parameters
const result = await prisma.$queryRaw`
  SELECT * FROM users WHERE name = ${userInput}
`;

Python (SQLAlchemy)

# VEILIG — parameterized
result = session.execute(
    text("SELECT * FROM users WHERE email = :email"),
    {"email": user_input}
)

PHP (PDO)

// VEILIG — prepared statement
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);

Aanvullende beschermingslagen

Laag 2: Input validatie

Valideer invoer op type, lengte en formaat. Dit vangt een deel van de aanvallen op maar is geen vervanging voor parameterized queries.

const emailSchema = z.string().email().max(255);
const idSchema = z.number().int().positive();

Laag 3: Least privilege

Geef de database-gebruiker van uw applicatie alleen de rechten die nodig zijn:

RechtNodig voor webapplicatie?
SELECTJa
INSERTMeestal ja
UPDATEMeestal ja
DELETEBeperkt (soft delete overwegen)
DROPNee
CREATENee (migraties via apart account)
GRANTNooit

Laag 4: Stored procedures

Voor complexe queries kunt u stored procedures gebruiken, die server-side worden gecompileerd en minder vatbaar zijn voor injectie.

Laag 5: WAF (Web Application Firewall)

Een WAF kan bekende SQL-injectie patronen blokkeren, maar is een vangnet — niet een primaire verdediging.

Laag 6: Foutafhandeling

Toon nooit database-foutmeldingen aan gebruikers in productie:

// ONVEILIG
catch (error) {
  res.status(500).json({ error: error.message }); // Onthult database-structuur
}

// VEILIG
catch (error) {
  logger.error({ error: error.message }, 'Database query failed');
  res.status(500).json({ error: 'Er is een fout opgetreden' });
}

Veelgemaakte fouten

FoutRisico
String concatenatie voor queriesDirecte SQL-injectie kwetsbaarheid
Raw queries zonder parametersOmzeilt ORM-bescherming
Vertrouwen op client-side validatieAanvaller stuurt direct HTTP-requests
Database-fouten tonen in productieInformatielekkage over structuur
Te brede database-rechtenAanvaller kan DROP TABLE uitvoeren
Alleen WAF als beschermingWAF-bypass technieken zijn bekend
Vergeten van LIKE-clausules% en _ zijn wildcards die moeten worden geëscaped

SQL-injectie in context: NIS2 en AVG

SQL-injectie raakt direct aan compliance:

  • NIS2: organisaties moeten passende beveiligingsmaatregelen implementeren. SQL-injectie kwetsbaarheden getuigen van nalatigheid.
  • AVG: een datalek via SQL-injectie is meldingsplichtig bij de AP. Als u onvoldoende maatregelen had genomen, riskeert u een boete bovenop de reputatieschade.

Testen op SQL-injectie

Handmatige tests

Veelgebruikte testpatronen voor invoervelden:

  • Enkele aanhalingsteken: '
  • Boolean condities: ' OR '1'='1
  • Commentaar: --, #, /* */
  • UNION queries: ' UNION SELECT null, null --
  • Time-based: ' OR SLEEP(5) --

Geautomatiseerd

Geautomatiseerde security scanners testen systematisch alle invoerpunten op SQL-injectie kwetsbaarheden, inclusief blinde varianten die handmatig moeilijk te detecteren zijn.

Conclusie

SQL-injectie is een volledig te voorkomen kwetsbaarheid. Gebruik altijd parameterized queries, valideer invoer, beperk database-rechten en toon geen technische foutmeldingen in productie. Er is geen reden om in 2026 nog kwetsbaar te zijn voor SQLi.


Scan uw website gratis met WarDek — OWASP, NIS2, AVG, AI Act compliance in één scan.

#SQL injectie#database#beveiliging#OWASP

Scannez votre site gratuitement

WarDek détecte les vulnérabilités mentionnées dans cet article en quelques secondes.