Pourquoi êtes-vous ici ?
Vous avez déjà entendu parler des attaques par injection SQL JavaScript, mais vous n'êtes pas entièrement sûr de ce à quoi elles ressemblent en pratique ou si vous devez vous en préoccuper. Peut-être essayez-vous de comprendre à quel point cela pourrait être grave.
En bref, si vous développez des applications utilisant des bases de données SQL, comme MySQL et PostgreSQL, vous êtes exposé à des risques — vous n'êtes pas à l'abri des méthodes d'attaque qui affligent les développeurs et leurs bases de données depuis des décennies. En tant que développeur, il vous incombe de mettre en place des garde-fous qui protègent les données des utilisateurs et garantissent que votre infrastructure sous-jacente ne soit jamais compromise, explorée ou détournée.
Tous les nouveaux outils prétendent vous aider, mais ils ne font que complexifier le développement.
Vous pouvez ajouter un mapper objet-relationnel (ORM) comme Sequelize et TypeORM pour simplifier votre travail avec les bases de données SQL comme MySQL et PostgreSQL, mais ils ne vous déchargent pas complètement des risques. Les pare-feu d'applications web (WAF) vous aident à bloquer les attaques au niveau du réseau, mais nécessitent une infrastructure coûteuse et une maintenance constante. Les analyseurs de code peuvent vous aider à identifier les failles évidentes, mais sont beaucoup moins efficaces pour les inconnues inconnues et les techniques de zero-day latentes.
Nous vous présenterons une image claire de ce à quoi ressemblent les attaques par injection SQL, des risques qu'elles comportent et des erreurs de développement qui les rendent possibles. Ensuite, nous ferons encore mieux en vous guidant à travers l'installation d'un correctif global afin que vous sachiez, avec certitude, que vos applications sont sécurisées.
Attaques par injection SQL : exemples et implications
La définition la plus élémentaire d'une attaque par injection SQL est lorsqu'une application permet à une entrée utilisateur non validée et non assainie d'exécuter des requêtes de base de données, permettant à un attaquant de lire la base de données SQL, de modifier des enregistrements ou de les supprimer à sa guise.
Comme d'habitude, XKCD illustre le danger du SQL mieux que la plupart des scénarios sombres que nous pourrions imaginer :

À quoi ressemble une application JavaScript vulnérable ?
Commençons par un exemple simple en pseudocode : une application JavaScript avec un élément d'entrée qui permet aux utilisateurs de rechercher une base de données de chats. Dans l'exemple de code JavaScript ci-dessous, l'application répond aux requêtes POST sur le chemin /cats pour extraire l'entrée utilisateur du corps de la requête et se connecte à la base de données avec une requête pour renvoyer tous les chats ayant un identifiant correspondant. L'application affiche ensuite le chat en utilisant la réponse JSON.
app.post("/cats", (request, response) => {
const query = `SELECT * FROM cats WHERE id = ${request.body.id}`;
connection.query(query, (err, rows) => {
if(err) throw err;
response.json({
data: rows
});
});
});
Bien que cet exemple puisse sembler inoffensif pour ceux qui ne sont pas formés aux attaques par injection SQL, il est extrêmement vulnérable. Notamment, l'application ne tente pas de valider ou de nettoyer les entrées utilisateur pour les chaînes potentiellement dangereuses ou les méthodes d'encodage, et concatène directement l'entrée utilisateur dans la requête SQL, ce qui offre aux attaquants de multiples opportunités d'attaquer en utilisant des méthodes d'injection SQL courantes qui existent depuis des décennies.
Exemple de charges utiles d'attaque SQL JavaScript
L'injection SQL repose sur le fait de tromper votre base de données MySQL ou PostgreSQL pour qu'elle agisse ou réponde avec des données en dehors de la portée attendue, en raison de la manière dont votre application génère les requêtes SQL.
Le 1=1 est toujours vrai une attaque peut renvoyer toute la table des chats avec des astuces comme les apostrophes ou les guillemets, car 1=1 est en effet toujours VRAI :
- Les entrées de l'utilisateur :
BOBBY TABLES’ OR 1=’1 - La base de données exécute la requête SQL :
SELECT * FROM Users WHERE Cat = BOBBY TABLES OR 1=1;
De même, les attaquants peuvent exploiter une = est toujours vrai attaque pour renvoyer tous les chats, car ""="" est toujours VRAI :
- Les entrées de l'utilisateur :
" OR ""=" - La base de données exécute la requête SQL :
SELECT * FROM Cats WHERE CatId ="" or ""="";
Les attaquants exploitent souvent la manière dont les bases de données gèrent les commentaires en ligne, et en insérant des commentaires (/* … */) dans une requête, ils peuvent masquer leur intention ou contourner les filtres.
- Les entrées de l'utilisateur :
DR/*hello world*/OP/*sneak attack*/ TABLE Cats; - La base de données exécute la requête SQL :
DROP TABLE Cats;
Une autre stratégie courante d'injection SQL JavaScript est l'empilement de requêtes (query stacking), qui permet aux attaquants de commencer par une chaîne de caractères inoffensive, puis d'utiliser un point-virgule (;) pour terminer cette instruction et en commencer une autre contenant leur injection. Les attaquants utilisent souvent l'empilement de requêtes pour supprimer des bases de données entières d'un seul coup avec une commande DROP TABLE :
- Les entrées de l'utilisateur :
Bobby; DROP TABLE Cats -- - L'application construit sa requête SQL :
const query = "SELECT * FROM Cats WHERE CatId = " + input; - La base de données exécute la requête SQL :
SELECT * FROM Cats WHERE CatId = BOBBY; DROP TABLE Cats;
Qu'en est-il des attaques par injection NoSQL ?
Les attaques par injection NoSQL sont tout aussi dangereuses pour la sécurité de votre application et des données utilisateur, mais n'affectent que les piles technologiques utilisant des bases de données comme MongoDB. La principale différence réside dans le style des attaques, car les requêtes SQL et NoSQL utilisent une syntaxe entièrement unique qui ne se traduit pas d'une catégorie à l'autre.
Si vous utilisez une base de données SQL, vous n'êtes pas exposé aux attaques par injection NoSQL, et vice versa.
La voie classique : corriger manuellement toutes vos vulnérabilités d'injection SQL
À ce stade, vous pourriez être moins intéressé par les différentes techniques d'injection possibles et plus par la manière de protéger les données que vous avez dans MySQL ou PostgreSQL.
- Utiliser des requêtes paramétrées: SQL dispose d'une fonctionnalité pour déconnecter l'exécution des requêtes et des valeurs, protégeant ainsi la base de données des attaques par injection. Avec l'exemple JavaScript/Node.js ci-dessus, vous pouvez utiliser un espace réservé dans votre requête SQL avec un point d'interrogation (
?). Leconnection.query()la méthode prend ensuite le paramètre dans son deuxième argument, fournissant les mêmes résultats dans une méthode à l'épreuve des injections.
app.post("/cats", (request, response) => {
const query = `SELECT * FROM Cats WHERE id = ?`;
const value = request.body.id;
connection.query(query, value, (err, rows) => {
if(err) throw err;
response.json({
data: rows
});
});
});
- Valider et assainir les entrées utilisateur: Bien que les requêtes paramétrées puissent aider à protéger votre base de données SQL contre les intrusions et les attaques, vous pouvez également empêcher les utilisateurs de saisir des chaînes potentiellement dangereuses dans votre application.
Une option consiste à ajouter des bibliothèques open source pour l'assainissement et la validation à votre application. Par exemple, vous pouvez utiliser validator.js dans l'écosystème JavaScript/Node.js pour vérifier qu'un utilisateur tente de saisir une véritable adresse e-mail – et non une attaque par injection SQL – dans votre formulaire d'inscription.
Vous pouvez également développer des validateurs personnalisés basés sur des regex pour effectuer un travail similaire, mais vous aurez un chemin énormément chronophage et complexe devant vous, avec de la recherche et des tonnes de tests manuels. De plus, pouvez-vous vraiment interpréter cet exemple de regex pour la validation d'e-mail ?const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
La même idée s'applique à la prévention de chaînes de caractères telles que…’ OR 1-’1.Vous pouvez essayer de rechercher et de saisir toutes ces opportunités vous-même, mais vous préféreriez probablement consacrer votre temps à développer de nouvelles fonctionnalités.
- Déployer des WAF ou des plateformes de sécurité basées sur des agents : Bien que ces solutions puissent bloquer les attaques SQL avant même qu'elles n'atteignent votre application, ou du moins vous alerter en temps réel lorsque des attaques se produisent, elles comportent quelques mises en garde.
Premièrement, elles sont souvent coûteuses et vous obligent à déployer une nouvelle infrastructure sur site ou dans le cloud, ce qui est souvent bien plus complexe que ce à quoi vous vous êtes engagé en tant que développeur souhaitant simplement livrer en production. Deuxièmement, elles nécessitent une maintenance plus manuelle pour mettre à jour l'ensemble de règles, vous distrayant d'autres interventions manuelles pour les injections SQL. Enfin, elles ajoutent souvent une charge de calcul supplémentaire, ou redirigent toutes les requêtes via leur plateforme pour analyse, ajoutant de la latence et nuisant à l'expérience de l'utilisateur final.
Le grand problème est que les opportunités d'attaques par injection SQL sont comme des mauvaises herbes – vous pouvez les éliminer une fois en utilisant ces outils, mais vous devez être constamment vigilant sur l'ensemble de votre base de code pour vous assurer qu'elles ne repoussent jamais.
Une approche alternative pour résoudre les attaques par injection SQL JavaScript : Aikido Firewall
Aikido Security a récemment lancé Firewall, un moteur de sécurité gratuit et open source qui vous protège de manière autonome contre les attaques par injection SQL, et bien plus encore.
Si vous n'utilisez pas Node.js, sachez que nous prendrons en charge d'autres langages et frameworks à l'avenir. Vous pouvez toujours vous abonner à notre newsletter produit pour savoir exactement quand Firewall s'étendra au-delà du monde JavaScript, ou nous envoyer un e-mail à hello@aikido.dev si vous souhaitez proposer un langage spécifique.
Tester une application vulnérable à l'injection SQL JavaScript
Utilisons une application exemple fournie avec le dépôt open source pour illustrer le fonctionnement d'Aikido Firewall. Vous aurez également besoin de Docker/Docker Compose pour déployer une base de données MySQL locale.
Commencez par forker le dépôt firewall-node et en clonant ce fork sur votre poste de travail local.
git clone https://github.com/<YOUR-GITHUB-USERNAME>/firewall-node.gitcd firewall-node
Utilisez Docker pour déployer une base de données MySQL locale sur le port 27015. Ce fichier docker-compose.yml crée également des conteneurs s3mock, MongoDB et PostgreSQL, car il a été conçu pour aider l'équipe Aikido à tester la manière dont Firewall bloque diverses attaques.
docker-compose -f sample-apps/docker-compose.yml up -d
Ensuite, lancez l'application exemple :
node sample-apps/express-mysql2/app.js
Ouvert http://localhost:4000 dans votre navigateur pour découvrir la très simple application de chat. Dans la zone de texte, saisissez quelques noms de chats et cliquez sur le Ajouter bouton. Pour tester l'injection SQL, vous pouvez soit cliquer sur le Injection de test liez ou saisissez ce qui suit dans la zone de texte : Kitty'); DELETE FROM cats;-- H et cliquez Ajouter à nouveau. Quoi qu'il en soit, l'application vous permet d'empiler plusieurs requêtes ensemble en utilisant des commentaires de requête astucieux, supprimant ainsi toute la base de données cats.
Comment cela se produit-il ? Comme nous l'avons précédemment averti, cette application se contente d'ajouter tout saisie utilisateur à la fin de la requête SQL, ce qui est intrinsèquement dangereux.
const query = `INSERT INTO cats(petname) VALUES ('${name}');`
Les conséquences peuvent être minimes ici, mais il n'est pas difficile d'imaginer comment cette erreur souvent honnête peut avoir des conséquences désastreuses pour votre application de production.
Bloquer les injections SQL JavaScript avec Aikido Firewall
Voyons maintenant avec quelle rapidité notre moteur de sécurité open source bloque les attaques par injection SQL JavaScript sans avoir à corriger manuellement chaque interaction avec la base de données dans votre code.
Si vous n'avez pas encore de compte Aikido, allez-y et créez-en un gratuitement. Si vous en avez déjà un, connectez-vous et connectez votre compte GitHub. Au cours de ce processus, accordez à Aikido l'accès en lecture à votre fork du firewall-node projet.
Aller à la Tableau de bord Firewall et cliquez sur Ajouter un service. Donnez un nom à votre service et choisissez à nouveau votre fork pour le firewall-node projet.

Aikido vous explique ensuite comment installer et implémenter Aikido Firewall. Puisque nous utilisons l'application exemple, ce travail est déjà fait pour vous, mais c'est une référence utile pour savoir comment vous pourriez intégrer notre moteur de sécurité open source à toutes vos applications Node.js qui pourraient être vulnérables aux attaques par injection SQL JavaScript.

Cliquez sur le Générer un jeton bouton pour créer un jeton afin de permettre à Aikido Firewall de transmettre en toute sécurité les informations sur les attaques par injection SQL bloquées à la plateforme de sécurité Aikido. Copiez le jeton généré, qui commence par AIK_RUNTIME…, puis retournez à votre terminal pour relancer l'application d'exemple, mais cette fois avec le Firewall entièrement activé en mode blocage :
AIKIDO_TOKEN=<YOUR-AIKIDO-TOKEN> AIKIDO_DEBUG=true AIKIDO_BLOCKING=true node sample-apps/express-mysql2/app.js
Ouvert localhost:4000 et invoquez à nouveau l'attaque par injection SQL incluse. Cette fois, Aikido vous bloquera au niveau du navigateur, affichera une sortie dans les journaux de votre serveur web local et générera un nouvel événement. Cliquez dessus pour voir les détails complets de la tentative d'injection SQL, y compris la charge utile et l'endroit où votre application a généré la requête SQL dangereuse.

Au lieu de vous soucier de protéger indéfiniment vos applications contre les attaques par injection SQL JavaScript, qu'elles soient critiques ou encore inconnues, Aikido Firewall offre un blocage complet et une observabilité sophistiquée qui vous tient informé des sources d'attaque, des charges utiles courantes et des points faibles potentiels.
Quelle est la suite ?
Vous pouvez installer et implémenter Aikido Firewall gratuitement dans toutes vos applications basées sur Node.js. Notre moteur de sécurité embarqué open source protège votre infrastructure et les données de vos utilisateurs contre les attaques par injection SQL JavaScript, l'injection de commandes, la pollution de prototype, le path traversal, et d'autres à venir prochainement.
Nous ne prétendons pas que Firewall doive se substituer aux bonnes pratiques de développement pour se prémunir contre les injections SQL, telles que l'utilisation de requêtes paramétrées ou la méfiance systématique envers les entrées utilisateur. Cependant, nous savons par expérience personnelle qu'aucun développeur n'est infaillible. Aucune base de code n'est exempte de défauts, et des erreurs honnêtes surviennent constamment.
Considérez Firewall comme un correctif global pour l'injection SQL. Contrairement aux regex développées sur mesure, aux WAFs générant de la latence ou aux agents de sécurité complexes qui coûtent cher, il fait ce travail extraordinairement bien et avec un impact négligeable — entièrement gratuitement.
Si ce que vous avez vu vous plaît, consultez notre feuille de route et mettez une étoile à notre dépôt GitHub (https://github.com/AikidoSec/firewall-node). ⭐
Sécurisez votre logiciel dès maintenant.




