Comment choisir un scanner d’injection SQL

Yuta Matsuyama

Chercheur en sécurité, TECHFUND Inc.

Mis à jour:

À qui s’adresse cet article: Équipes de développement et de sécurité choisissant des outils de test d’injection SQL.

Réponse pratique

Pour rechercher des injections SQL, commencez par déterminer si vous souhaitez examiner une application Web en fonctionnement ou son code source. Dans le premier cas, utilisez des tests dynamiques avec des outils comme ZAP ou sqlmap ; dans le second, recourez à l’analyse de code. En pratique, il est utile de combiner les deux pour vérifier les parties importantes.

Définir le point d’entrée des tests avant de choisir un scanner

Supposons, par exemple, qu’une valeur saisie dans un formulaire de recherche soit intégrée telle quelle à une instruction SQL. Les tests dynamiques envoient de véritables requêtes et recherchent des problèmes en observant notamment les différences entre les réponses. L’analyse de code suit le parcours de la valeur, depuis son point d’entrée jusqu’aux requêtes auxquelles elle est transmise.

Les tests dynamiques ne peuvent pas examiner les pages ou les API auxquelles ils ne parviennent pas à accéder. L’analyse de code peut elle aussi laisser passer des problèmes, selon les langages et les frameworks pris en charge, ainsi que la configuration du périmètre analysé. Même si une méthode ne produit aucun résultat, cela ne permet pas de conclure que l’autre est inutile.

Principaux outils et choix selon les besoins

ZAP : une option open source pour examiner une application Web dans son ensemble. Il dispose de règles de scan actif pour les injections SQL et permet de rechercher aussi d’autres vulnérabilités Web. Toutefois, ZAP Baseline effectue par défaut un scan passif : son exécution seule ne signifie donc pas qu’un test actif des injections SQL a été réalisé.

sqlmap : un outil open source adapté lorsqu’un point de saisie précis suscite des soupçons et que vous souhaitez concentrer les vérifications sur les injections SQL. Comme il propose non seulement la détection, mais aussi des fonctions d’automatisation de l’exploitation, définissez le périmètre autorisé et utilisez-le dans un environnement où les conséquences peuvent être limitées.

Burp Suite Professional : destiné aux personnes qui souhaitent combiner scanner et vérifications manuelles tout en examinant les requêtes HTTP. Le scanner automatique est inclus notamment dans l’édition payante Professional, mais pas dans la version gratuite Community Edition.

Wapiti : un outil open source permettant d’examiner une application Web en boîte noire depuis la ligne de commande. Sa documentation officielle présente des tests d’injection SQL fondés sur les erreurs, les valeurs booléennes et les différences de temps de réponse, ainsi que des scans d’API à partir de fichiers OpenAPI. Pour les cibles comprenant une SPA ou une authentification complexe, vérifiez au cas par cas que l’outil peut atteindre les parcours nécessaires.

Tous ces outils envoient des requêtes à une application en fonctionnement. Consignez avec les résultats l’étendue des éléments effectivement atteints : non seulement les pages, mais aussi les API accessibles après authentification, les interfaces d’administration et les droits propres à chaque utilisateur. Complétez cette approche par une analyse statique du code source, qui constitue une option distincte.

Lors de l’adoption d’un outil, comparer à la fois le nombre de détections et la couverture

Dans un même environnement de préproduction, préparez des entrées présentant des problèmes connus et des entrées traitées de manière sûre au moyen de requêtes paramétrées, puis comparez les résultats. Vérifiez non seulement que les premières sont détectées, mais aussi que les secondes ne sont pas signalées à tort. Assurez-vous également que les tests ne se sont pas interrompus en cours de route à cause de l’expiration de l’authentification et que tous les points d’entrée nécessaires ont pu être parcourus, y compris les API JSON.

Un scan peut avoir des conséquences sur les données de test ou sur la disponibilité. Obtenez l’autorisation explicite du propriétaire de la cible et convenez du périmètre, des horaires d’exécution, de la charge et des opérations à exclure. Si possible, effectuez les essais dans un environnement séparé de la production.

Vérifier aussi les points d’accès publics : l’exemple de MOVEit

Selon la fiche NVD de CVE-2023-34362 concernant MOVEit Transfer, une injection SQL pouvait permettre à un attaquant non authentifié d’accéder à la base de données. La fiche mentionne également une exploitation en mai et juin 2023. Pendant le développement, il est nécessaire de vérifier non seulement les traitements effectués après connexion, mais aussi les points d’accès publics. L’exemple ci-dessous est un exemple pédagogique fictif utilisant TypeScript et node-postgres : il ne s’agit ni de l’implémentation de MOVEit ni d’un code reproduisant cette CVE. Limitez les tests aux cibles pour lesquelles vous disposez d’une autorisation.

Après la détection, séparer les valeurs de la structure SQL

Le principe de base de la correction consiste à transmettre les valeurs externes comme paramètres, plutôt qu’à les concaténer à une chaîne SQL. Toutefois, la structure même du SQL, comme l’ordre de tri ou les noms de tables, ne peut pas toujours être gérée par la seule liaison de valeurs à des paramètres. Dans ce cas, sélectionnez une option parmi des choix fixes définis dans l’application.

Dans l’exemple suivant, la valeur recherchée est liée à un paramètre et l’ordre de tri est choisi parmi deux requêtes fixes. En complément, limitez les droits de l’utilisateur de la base de données au strict nécessaire et vérifiez séparément que l’utilisateur de l’application est autorisé à consulter ces données. Après la correction, vérifiez à nouveau que le problème initialement signalé a disparu et que la recherche habituelle fonctionne toujours.

Exemple pédagogique côté serveur utilisant node-postgres. La valeur est liée à $1, la clause ORDER BY est choisie parmi deux requêtes fixes et tout ordre de tri inconnu est refusé. L’autorisation des utilisateurs et la limitation des droits de la base de données au strict nécessaire doivent être gérées séparément. Vérifiez également que les guillemets sont traités comme des données, que les deux ordres de tri fonctionnent et que l’accès est refusé aux utilisateurs non autorisés.
import type { Pool } from "pg";

export async function findProducts(
  db: Pool, name: string, sort: string,
) {
  const queries = {
    newest: "SELECT id, name FROM products WHERE name = $1 ORDER BY created_at DESC, id DESC LIMIT 50",
    oldest: "SELECT id, name FROM products WHERE name = $1 ORDER BY created_at ASC, id ASC LIMIT 50",
  } as const;
  if (sort !== "newest" && sort !== "oldest") {
    throw new Error("Invalid sort");
  }
  return db.query(queries[sort], [name]);
}
Exemple : séparer la valeur recherchée de la structure SQL
  1. L’utilisateur saisit une valeur de recherche
  2. L’application lie la valeur à $1
  3. L’application transmet une requête fixe et la valeur à la base de données

Choisissez la structure SQL, comme ORDER BY, parmi des requêtes fixes autorisées. L’autorisation et les droits minimaux en base restent nécessaires séparément ; ce schéma ne garantit pas la sécurité.

Questions fréquentes

Un scanner garantit-il l’absence d’injection SQL ?

Non. La couverture, la configuration et les accès limitent la détection. Associez les tests à une revue du code.

Puis-je tester une application en production ?

Uniquement avec une autorisation explicite et un périmètre convenu. Les tests dynamiques peuvent affecter les données ou la disponibilité ; privilégiez un environnement contrôlé.

Sources et lectures

Comment Hi AUDIT Agent peut vous aider

Avec Hi AUDIT Agent, examinez les flux de données, les emplacements signalés et les corrections proposées dans le code. Vérifiez la couverture de l’injection SQL pour votre environnement et faites valider le résultat par une personne.

Créer un compte Hi AUDIT Agent