Prévention des injections SQL pour applications web

Security2026-09-12TryQuickToolBox

L'injection SQL reste l'une des vulnérabilités les plus critiques des applications web. Les attaquants l'exploitent pour voler des données, contourner l'authentification et même exécuter des commandes système. Si votre application construit des requêtes SQL en concaténant les entrées utilisateur, vous êtes à risque. Cet article explique comment fonctionne l'injection SQL et fournit des étapes pratiques pour la prévenir dans les applications web modernes.

Comment se produit une injection SQL

Une injection SQL se produit lorsque des données non fiables sont interprétées comme faisant partie d'une commande SQL. Par exemple, considérons un formulaire de connexion qui vérifie les identifiants avec cette requête :

SELECT * FROM users WHERE username = '$username' AND password = '$password';

Si un attaquant saisit ' OR '1'='1 comme nom d'utilisateur et n'importe quel mot de passe, la requête devient :

SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'anything';

Cela retourne tous les utilisateurs, contournant l'authentification. Des techniques similaires peuvent extraire des données, modifier des enregistrements ou supprimer des tables.

1. Utilisez des requêtes préparées (requêtes paramétrées)

Les requêtes préparées séparent le code SQL des données. La base de données reçoit d'abord la structure de la requête, puis les paramètres, de sorte que l'entrée utilisateur n'est jamais traitée comme du code SQL. C'est la défense la plus efficace.

Exemple en PHP avec PDO :

$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $userInput]);
$user = $stmt->fetch();

Exemple en Java avec JDBC :

String sql = "SELECT * FROM users WHERE email = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, userInput);
ResultSet rs = stmt.executeQuery();

Utilisez toujours des requêtes paramétrées pour toutes les données fournies par l'utilisateur, y compris les champs de recherche, les filtres et les paramètres de tri.

2. Validez et assainissez les entrées

Bien que les requêtes préparées soient primordiales, la validation des entrées ajoute une défense en profondeur. Vérifiez que les entrées correspondent aux formats attendus (par exemple, format d'e-mail, ID numérique) et rejetez tout ce qui est inattendu. Par exemple, si un ID doit être un entier, convertissez-le en int dans votre code. Évitez les listes noires de caractères comme les guillemets—les attaquants peuvent contourner ces filtres.

3. Utilisez un ORM en toute sécurité

Les ORM comme Hibernate, Entity Framework et Sequelize utilisent généralement des requêtes paramétrées par défaut. Cependant, ils permettent souvent des fragments SQL bruts. Soyez prudent avec les méthodes qui acceptent des chaînes brutes :

Consultez toujours la documentation de votre ORM pour construire des requêtes sécurisées.

4. Échappez les données si les requêtes préparées sont impossibles

Dans de rares cas où vous devez construire du SQL dynamique (par exemple, des noms de tables dynamiques), utilisez la fonction d'échappement de votre pilote de base de données. Pour MySQL, mysqli_real_escape_string() échappe les caractères spéciaux. Mais rappelez-vous : l'échappement n'est pas aussi robuste que les requêtes préparées et doit être un dernier recours.

5. Appliquez le principe du moindre privilège aux comptes de base de données

Ne vous connectez pas à la base de données en tant que root ou avec un utilisateur disposant de tous les privilèges. Créez un utilisateur de base de données dédié pour votre application avec uniquement les permissions nécessaires (SELECT, INSERT, UPDATE, DELETE sur des tables spécifiques). Cela limite les dégâts en cas d'injection.

6. Utilisez un pare-feu d'application web (WAF)

Un WAF peut détecter et bloquer les schémas d'injection SQL courants. Bien que ne remplaçant pas un codage sécurisé, il fournit une couche supplémentaire. De nombreux fournisseurs cloud proposent des WAF managés faciles à activer.

7. Tests de sécurité réguliers

Testez votre application pour les vulnérabilités d'injection SQL à l'aide de scanners automatisés ou de tests d'intrusion manuels. Des outils comme SQLMap peuvent aider à identifier les problèmes. Intégrez les tests de sécurité dans votre pipeline CI/CD pour détecter les régressions tôt.

Comparaison des techniques de prévention

Technique Efficacité Facilité de mise en œuvre
Requêtes préparées Élevée Facile (intégré à la plupart des pilotes)
Validation des entrées Moyenne Modérée
Utilisation sécurisée d'un ORM Élevée Facile si conscient
Échappement Moyenne Facile mais sujet aux erreurs
Moindre privilège Moyenne Facile
WAF Faible à moyenne Facile (managé)

FAQ

Quelle est la méthode la plus efficace pour prévenir l'injection SQL ?

L'utilisation de requêtes préparées avec des requêtes paramétrées est la méthode la plus efficace. Elle garantit que l'entrée utilisateur n'est jamais interprétée comme du code SQL.

La validation des entrées seule peut-elle prévenir l'injection SQL ?

Non. La validation des entrées est une bonne mesure de défense en profondeur, mais elle ne doit pas être utilisée seule. Les attaquants peuvent parfois contourner les règles de validation, alors utilisez toujours des requêtes préparées comme défense principale.

Les ORM sont-ils automatiquement protégés contre l'injection SQL ?

Les ORM sont généralement sûrs lorsqu'ils sont utilisés correctement, mais ils permettent souvent des requêtes SQL brutes qui peuvent être vulnérables si vous concaténez les entrées utilisateur. Utilisez toujours des requêtes paramétrées, même dans les méthodes ORM.

Pour plus de sécurité, envisagez d'utiliser un formateur JSON pour inspecter et valider en toute sécurité les réponses API sans exécuter de code malveillant.