Sécurité

Prévenir les Injections SQL : Guide Complet pour PME

Prévenir l'injection SQL : types d'attaques, détection et protection concrète via requêtes préparées, ORM et WAF. Guide PME.

18 mars 20264 min de lectureWarDek Team

L'injection SQL fait partie de la catégorie A03:2021 (Injection) du Top 10 OWASP et reste l'une des failles les plus exploitées. En 2023, elle a été impliquée dans plus de 30 % des violations de données touchant des PME européennes. Pourtant, elle est presque entièrement évitable avec les bonnes pratiques. Ce guide vous donne les outils concrets pour protéger votre application.

Qu'est-ce qu'une Injection SQL ?

Une injection SQL se produit lorsqu'un attaquant insère du code SQL malveillant dans un champ de saisie, et que ce code est exécuté par votre base de données. La cause fondamentale est toujours la même : des données utilisateur non filtrées sont directement concaténées dans une requête SQL.

Exemple d'un code vulnérable en PHP :

// DANGEREUX — ne jamais faire ça
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '" . $username . "'";
$result = $pdo->query($query);

Si l'utilisateur saisit admin' OR '1'='1, la requête devient :

SELECT * FROM users WHERE username = 'admin' OR '1'='1'

Cette requête retourne tous les utilisateurs, car '1'='1' est toujours vrai. L'attaquant contourne l'authentification.

Les 3 Types d'Injection SQL

1. Injection classique (In-band)

L'attaquant voit directement le résultat de l'injection dans la réponse de l'application. C'est la forme la plus simple à détecter, mais aussi la plus rapide à exploiter. Un champ de recherche mal protégé peut exposer l'intégralité de votre base de données en quelques minutes.

2. Injection aveugle (Blind)

L'application ne retourne pas les données directement, mais l'attaquant peut inférer des informations à travers le comportement de l'application :

  • Boolean-based : la page retourne un résultat différent selon que la condition est vraie ou fausse
  • Time-based : l'attaquant utilise SLEEP() ou WAITFOR DELAY pour déduire des informations selon le temps de réponse

Ces attaques sont plus lentes, mais automatisées avec des outils comme sqlmap, elles peuvent exfiltrer une base de données entière en quelques heures.

3. Second-order injection

Le payload SQL est d'abord stocké en base de données (parfois via un champ échappé correctement), puis réutilisé dans une autre requête sans protection. C'est la forme la plus insidieuse, souvent ignorée lors des audits basiques.

Comment Détecter une Vulnérabilité

Avant de corriger, identifier. Les signaux d'alerte dans votre code :

  • Concaténation de chaînes dans des requêtes SQL
  • Utilisation de $_GET, $_POST, $_COOKIE directement dans une requête
  • Messages d'erreur SQL visibles dans la réponse HTTP
  • Absence de validation côté serveur sur les paramètres numériques

Pour tester sans risque, des outils comme OWASP ZAP ou notre scanner WarDek peuvent identifier automatiquement les points d'entrée vulnérables. Consultez notre article sur les outils gratuits de pentest pour une liste complète.

4 Techniques de Protection

1. Requêtes préparées (Prepared Statements)

C'est la protection fondamentale. Les paramètres sont transmis séparément de la requête SQL, rendant l'injection structurellement impossible.

// SÉCURISÉ — avec PDO (PHP)
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
$user = $stmt->fetch();
# SÉCURISÉ — avec Python et psycopg2
cursor.execute(
    "SELECT * FROM users WHERE username = %s AND password = %s",
    (username, password)
)
// SÉCURISÉ — avec Node.js et pg
const result = await pool.query(
  'SELECT * FROM users WHERE username = $1 AND password = $2',
  [username, password]
)

La règle est simple : jamais de concaténation de chaînes dans vos requêtes SQL. Toujours utiliser des paramètres liés.

2. ORM (Object-Relational Mapping)

Les ORM modernes génèrent automatiquement des requêtes préparées. Utiliser Prisma, Hibernate, Eloquent ou SQLAlchemy correctement vous protège par défaut.

// Prisma — injection impossible par construction
const user = await prisma.user.findFirst({
  where: {
    username: username,
    password: hashedPassword,
  },
})

Attention : les ORM ne vous protègent pas si vous utilisez leurs fonctionnalités de requêtes brutes ($queryRaw, executeQuery) sans paramétrage.

3. Validation et assainissement des entrées

Même avec des requêtes préparées, valider et typer vos entrées reste une bonne pratique de défense en profondeur :

import { z } from 'zod'

const searchSchema = z.object({
  query: z.string().min(1).max(100).regex(/^[a-zA-Z0-9\s\-_]+$/),
  page: z.coerce.number().int().min(1).max(1000),
})

const parsed = searchSchema.safeParse(req.query)
if (!parsed.success) {
  return res.status(400).json({ error: 'Paramètres invalides' })
}

4. WAF (Web Application Firewall)

Un WAF analyse le trafic HTTP et bloque les patterns d'attaque connus avant qu'ils atteignent votre application. Cloudflare, AWS WAF ou les solutions open-source comme ModSecurity offrent une protection supplémentaire.

Un WAF est une couche de défense complémentaire, pas un substitut aux requêtes préparées. Une application correctement codée reste votre première ligne de défense.

Principe du Moindre Privilège

Au-delà du code, limitez les droits de l'utilisateur base de données de votre application. Si votre application n'a besoin que de lire et écrire des données métier, son compte ne doit pas avoir les droits DROP TABLE ou accès aux tables système.

-- Créer un utilisateur avec droits limités
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON app_database.* TO 'app_user'@'localhost';
-- Pas de GRANT ALL, pas de super-privilèges

Que Faire si Vous Suspectez une Attaque

  1. Activez les logs SQL et cherchez les patterns anormaux (multiples OR, UNION SELECT, --)
  2. Vérifiez vos logs d'accès pour des requêtes avec des caractères spéciaux dans les paramètres
  3. Auditez les données sensibles : des enregistrements accédés sans action utilisateur correspondante sont suspects
  4. Consultez également notre guide sur la protection XSS et l'OWASP Top 10 API 2025 pour une vision globale

Surveiller en Continu

La sécurité n'est pas un état, c'est un processus. Une nouvelle fonctionnalité ajoutée par un développeur junior, une librairie tierce mise à jour, un paramètre oublié lors d'un refactoring — autant de vecteurs de réintroduction de vulnérabilités.

WarDek scanne automatiquement vos endpoints à la recherche d'injections SQL potentielles, en testant vos paramètres avec des payloads réels dans un environnement sécurisé. Chaque scan génère un rapport priorisé avec les corrections recommandées.

L'injection SQL est évitable à 100 %. Il n'y a aucune raison acceptable de laisser cette vulnérabilité dans une application en production.

Tester mon site gratuitement avec WarDek →

#injection-sql#owasp#base-de-donnees#securite-web#pme

Scannez votre site gratuitement

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