SQL Injection dans le développement mobile : ce que c'est, méthodes d'attaque et protection

Auteur : IT Sectr Publié le : 2026-04-06 Temps de lecture : 9 min

SQL Injection est un type d'attaque sur la base de données d'une application où un attaquant injecte du code SQL malveillant dans les paramètres de requête, obtenant un accès non autorisé aux données ou la possibilité de les modifier. Selon l'OWASP (2025), SQL Injection reste l'une des vulnérabilités critiques pouvant conduire à un compromis total de la base de données. L'injection de code SQL permet à l'attaquant de lire, modifier et supprimer des enregistrements, et dans certains cas, d'accéder au système d'exploitation du serveur.

Points clés

  • SQL Injection — injection de code SQL via les paramètres utilisateur, modifiant la logique de la requête à la base de données
  • Paramétrisation des requêtes — la méthode de protection principale : séparer le code SQL des données à l'aide de prepared statements
  • Types d'attaques — injection classique (via WHERE), Blind SQLi (inférences logiques), UNION-based (lecture d'autres tables)
  • Error-based SQLi — extraction de données via les messages d'erreur de la base de données
  • Frameworks ORM — réduisent le risque SQLi lorsqu'ils sont utilisés correctement, mais ne l'éliminent pas complètement

Qu'est-ce que SQL Injection ?

SQL Injection est une vulnérabilité qui se produit lorsqu'une application construit des requêtes SQL par concaténation de chaînes avec des données utilisateur. Un attaquant transmet une chaîne spécialement conçue dans un paramètre de requête qui modifie la structure de la commande SQL. Au lieu d'être des données, la chaîne injectée devient une partie du code SQL, permettant à l'attaquant d'exécuter des requêtes arbitraires contre la base de données. Selon le Rapport sur les violations de données de Verizon (2025), SQL Injection est présente dans 8% de toutes les violations de données étudiées.

Pourquoi SQL Injection est-il encore d'actualité ?

Malgré une vulnérabilité bien connue (première mention à la fin des années 1990), SQL Injection est toujours présent dans les applications modernes. La raison est l'erreur humaine : les développeurs écrivent du code avec concaténation de chaînes, le code hérité n'est pas refactorisé et les frameworks ORM sont utilisés incorrectement (par exemple, des requêtes raw avec interpolation de chaînes). Selon Veracode (2026), environ 14% de toutes les applications scannées contiennent au moins une vulnérabilité SQLi.

Que peut faire un attaquant ?

Une injection SQL réussie donne à l'attaquant un large éventail de capacités : lire n'importe quelle table de la base de données, y compris les hachages de mots de passe et les données personnelles des utilisateurs ; modifier et supprimer des enregistrements ; exécuter des opérations administratives (DROP TABLE, TRUNCATE) ; et dans certaines configurations, l'exécution de commandes à distance via xp_cmdshell (MSSQL) ou INTO OUTFILE (MySQL). Les conséquences vont de la fuite de données utilisateur à la perte totale de contrôle du système.

Types d'injections SQL

Les injections SQL sont classées selon la méthode d'extraction des données de la base de données. Le choix de la méthode dépend de la façon dont l'application traite les résultats des requêtes et les messages d'erreur. La classification OWASP identifie trois types principaux : In-band (données extraites via le même canal), Inferential/Blind (inférences logiques) et Out-of-band (données transmises via un autre canal).

TypeMéthode d'extractionComplexitéFréquence
In-band (classique)Directement via le résultat de la requêteFaibleÉlevée
Blind SQLiInférences logiques à partir des réponses du serveurÉlevéeMoyenne
Out-of-bandVia un canal externe (DNS, HTTP)MoyenneFaible

In-band SQL Injection (Classique)

Le type le plus courant. Un attaquant injecte du code SQL dans un paramètre de requête, et le résultat de l'injection est directement visible dans la réponse du serveur. Deux sous-types : Error-based (via les messages d'erreur de la BD) et UNION-based (via l'opérateur UNION SELECT). Error-based utilise les informations des messages d'erreur, comme une erreur de syntaxe MySQL qui peut révéler le nom de la table ou la structure de la requête. UNION-based permet de combiner les résultats d'une requête légitime avec des données d'autres tables de la base de données.

Blind SQL Injection (Aveugle)

Utilisée lorsque l'application n'affiche pas les résultats de la requête ni les messages d'erreur. Un attaquant pose des questions oui/non en envoyant des requêtes avec des conditions logiques et en analysant les différences dans les réponses du serveur (par exemple, le temps de réponse ou le contenu de la page). Time-based Blind SQLi utilise des fonctions de retard (SLEEP, WAITFOR DELAY) pour confirmer les conditions — si la page met plus de temps à charger, la condition est vraie. Cette méthode est très lente — l'extraction d'un seul enregistrement peut prendre des heures.

python
# Exemple de Blind SQL Injection (basée sur le temps)
# Si SQLi est vulnérable, SLEEP(2) s'exécute si la condition est remplie
import requests
import time

payload = "' OR IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a',SLEEP(2),0) -- "
url = "http://example.com/user?id=1" + payload

start = time.time()
response = requests.get(url)
elapsed = time.time() - start

# Si la réponse arrive après >2 secondes — la première lettre du mot de passe est 'a'
print(f"Time: {elapsed:.2f}s - First letter is 'a'" if elapsed > 2 else "First letter is not 'a'")

Out-of-band SQL Injection

Les données sont transmises non pas via la réponse HTTP mais par des canaux alternatifs : requêtes DNS, requêtes HTTP vers un serveur externe, SMTP. Utilisée lorsque l'application ne renvoie pas les résultats de la requête ni n'affiche les erreurs. MySQL prend en charge la fonction LOAD_FILE(), qui peut déclencher une requête DNS, et MSSQL dispose de xp_dirtree pour envoyer des données à un serveur SMB distant. Out-of-band SQL Injection est efficace mais nécessite une configuration supplémentaire du serveur de l'attaquant et des fonctions BD spécifiques.

Comment fonctionne l'injection SQL ?

Le mécanisme de SQL Injection repose sur le fait que SQL utilise des guillemets pour les littéraux de chaîne. Si une application insère l'entrée de l'utilisateur directement dans une requête SQL sans l'échapper, un attaquant peut « fermer » la chaîne et ajouter du code SQL arbitraire. Par exemple, dans la requête SELECT * FROM users WHERE name = '$input', l'insertion de ' OR '1'='1 la transforme en SELECT * FROM users WHERE name = '' OR '1'='1', qui retourne tous les utilisateurs.

Exemple classique : Contournement d'authentification

Considérons un formulaire de connexion avec la requête SELECT * FROM users WHERE username = '$user' AND password = '$pass'. Si un attaquant saisit admin' -- dans le champ nom d'utilisateur et laisse le mot de passe vide, la requête résultante devient SELECT * FROM users WHERE username = 'admin' -- ' AND password = ''. Les caractères -- commentent le reste de la requête, désactivant la vérification du mot de passe. Le serveur renvoie l'enregistrement de l'utilisateur admin, et l'attaquant se connecte sans connaître le mot de passe.

python
# Exemple de SQL Injection — Contournement d'authentification
# CODE VULNÉRABLE : concaténation directe de chaînes
def login_vulnerable(username, password):
    query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
    cursor.execute(query)
    return cursor.fetchone() is not None

# username = "admin' --" annule la vérification du mot de passe
# VERSION SÉCURISÉE : requête paramétrée
def login_secure(username, password):
    query = "SELECT * FROM users WHERE username = %s AND password = %s"
    cursor.execute(query, (username, password))
    return cursor.fetchone() is not None

UNION-based : Lecture d'autres tables

L'opérateur UNION SELECT permet de combiner les résultats de deux requêtes SELECT. Si un attaquant trouve un paramètre vulnérable, il ajoute UNION SELECT avec une requête d'une autre table. Par exemple : ' UNION SELECT username, password FROM admins --. La condition de succès est que le nombre de colonnes dans les deux requêtes doit correspondre. Le nombre de colonnes est déterminé via ORDER BY (en insérant ' ORDER BY 1--, puis 2, 3... jusqu'à une erreur). Connaissant le nombre de colonnes, l'attaquant insère UNION SELECT avec le même nombre de champs.

SQL Injection dans les applications mobiles

Les applications mobiles sont confrontées à SQL Injection à la fois côté serveur (API) et côté client — dans les bases de données locales (SQLite, Realm). Alors que la SQLi côté serveur dans les API mobiles est similaire aux applications web, les bases de données locales créent un vecteur supplémentaire. Si une application stocke des données dans SQLite et exécute des requêtes avec concaténation de chaînes, les données malveillantes entrant dans la base de données locale via l'API peuvent déclencher une SQLi lors du traitement ultérieur.

SQL Injection dans SQLite sur Android/iOS

La base de données locale SQLite sur un appareil est également vulnérable à SQL Injection si l'application construit des requêtes en concaténant des chaînes. Les Content Providers sur Android et Core Data sur iOS utilisent la paramétrisation par défaut, mais les requêtes raw nécessitent l'attention du développeur. SQLite ne prend pas en charge les requêtes multiples séparées par des points-virgules, ce qui limite les options de l'attaquant mais ne protège pas contre la lecture de données via des conditions WHERE. Utilisez toujours selectionArgs dans Android et NSPredicate avec paramètres dans iOS.

SQL Injection via l'API de l'application mobile

L'API avec laquelle une application mobile communique est vulnérable comme n'importe quel serveur web. Les développeurs mobiles supposent souvent que la SQLi n'est qu'un problème de backend, mais la vulnérabilité se produit au point de terminaison de l'API qui accepte les paramètres du client. La séparation des responsabilités ne protège pas : si le développeur backend a oublié de paramétrer la requête, l'application mobile de l'utilisateur devient un vecteur d'attaque. Exigez du backend l'utilisation d'ORM ou de prepared statements.

kotlin
// Exemple de SQL Injection dans SQLite local sur Android
// CODE VULNÉRABLE : concaténation directe
fun getUserVulnerable(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = $userId", null
    )
}

// VERSION SÉCURISÉE : paramétrisation via selectionArgs
fun getUserSecure(db: SQLiteDatabase, userId: String): Cursor {
    return db.rawQuery(
        "SELECT * FROM users WHERE id = ?",
        arrayOf(userId)
    )
}

Méthodes de prévention de SQL Injection

La protection contre SQL Injection repose sur un principe simple : ne faites jamais confiance aux entrées utilisateur dans les requêtes SQL. La seule méthode fiable est la paramétrisation des requêtes (prepared statements), où le code SQL et les données sont passés séparément. Toutes les autres méthodes — échappement, validation, WAF — sont des couches de sécurité supplémentaires mais ne remplacent pas la paramétrisation. Selon l'OWASP (2025), la paramétrisation prévient 100% des attaques SQL Injection.

Prepared Statements (Requêtes paramétrées)

Lors de l'utilisation de prepared statements, la requête SQL est d'abord compilée par le serveur de BD sans données, puis les valeurs des paramètres sont passées séparément. La base de données traite les paramètres comme des données, pas comme du code exécutable. Même si un attaquant transmet ' OR '1'='1, la base de données l'interprète comme une valeur de chaîne, pas comme du code SQL. Les prepared statements sont pris en charge par tous les langages et frameworks modernes : PDO en PHP, PreparedStatement en Java, cursor.execute en Python.

Frameworks ORM et Query Builders

Les ORM modernes (Hibernate, Entity Framework, SQLAlchemy, Room) utilisent automatiquement la paramétrisation lors de l'exécution des requêtes, à moins que le développeur ne passe aux requêtes raw. Cependant, les ORM ne protègent pas complètement : des constructions comme @Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true) dans JPA nécessitent le passage de paramètres via des paramètres nommés, pas par concaténation. Les Query Builders (Knex, jOOQ) paramètrent également les requêtes par défaut si les méthodes raw ne sont pas utilisées.

Échappement de chaînes (non recommandé comme méthode principale)

L'échappement des caractères spéciaux (mysql_real_escape_string) est une méthode obsolète qui ne protège pas contre tous les types de SQL Injection. Le problème : l'échappement dépend de l'encodage et peut être contourné lors de l'utilisation d'encodages multi-octets (par exemple, GBK dans les systèmes asiatiques). Utilisez l'échappement uniquement dans le code hérité où la paramétrisation est impossible, et toujours en combinaison avec une validation stricte du type des données d'entrée.

MéthodeEfficacitéRecommandation
Prepared Statements100%Obligatoire pour toutes les requêtes
ORM (utilisation correcte)99%Recommandé
Échappement de chaînes70% (dépend de l'encodage)Hérité uniquement
Validation d'entrée (white-list)50% (nombres uniquement)Supplémentaire
WAF (Web Application Firewall)60%Supplémentaire

Principe du moindre privilège pour la BD

Le compte de l'application doit avoir les privilèges minimaux nécessaires : SELECT, INSERT, UPDATE, DELETE — uniquement sur les tables dont l'application a réellement besoin. Interdisez l'utilisation de DROP, TRUNCATE, CREATE pour le compte de l'application. Cela limite les dommages même en cas d'injection SQL réussie : l'attaquant ne pourra pas supprimer des tables ni exécuter des opérations administratives.

Outils de détection des injections SQL

Les tests réguliers de SQL Injection doivent faire partie du pipeline de développement sécurisé. Une combinaison d'analyse statique, de scan dynamique et de tests de pénétration manuels donne les meilleurs résultats. Selon le Rapport de cybersécurité Synopsys (2025), les scanners automatisés trouvent jusqu'à 70% des vulnérabilités SQLi, mais les attaques Blind complexes nécessitent des tests manuels.

  • sqlmap — l'outil le plus populaire pour la détection et l'exploitation automatiques de SQL Injection
  • OWASP ZAP — un scanner DAST gratuit avec des modules de scan actif de SQLi
  • Burp Suite Scanner — un outil professionnel avec détection automatique de SQL Injection
  • SonarQube — analyse statique de code pour les vulnérabilités, y compris les modèles SQLi
  • CodeQL — analyse sémantique de code pour trouver les injections SQL dans le code source

Pour les applications mobiles, l'analyse de SQLite locale est également importante : vérifiez tous les appels rawQuery, les requêtes ContentProvider et les requêtes Room avec rawQuery. Outils : Android Studio Lint (détecte SQLi dans SQLite), MobSF (Mobile Security Framework) pour l'analyse statique et dynamique automatique d'APK/IPA. Il est également recommandé de tester les points de terminaison de l'API via sqlmap avec interception proxy du trafic de l'application mobile.

Questions fréquentes

Quelle est la différence entre SQL Injection et NoSQL Injection ?

SQL Injection attaque les bases de données relationnelles via des requêtes SQL. NoSQL Injection affecte les bases de données non relationnelles (MongoDB, Couchbase) via leurs opérateurs de requête ($gte, $ne, $where). Dans MongoDB, l'injection est possible si l'application construit un document BSON à partir d'une chaîne JSON. Les mécanismes de protection sont similaires : paramétrisation et validation de type.

Comment détecter SQL Injection dans le code soi-même ?

Trouvez tous les endroits où les requêtes SQL sont formées par concaténation de chaînes avec des données utilisateur. Recherchez des modèles comme "SELECT ... WHERE id = " + userId ou f"UPDATE ... SET name = '{name}'". Chacune de ces lignes est une injection SQL potentielle. Remplacez-les toutes par des requêtes paramétrées ou des prepared statements.

L'ORM protège-t-il automatiquement contre SQL Injection ?

Les frameworks ORM protègent automatiquement uniquement si vous utilisez leurs méthodes Query Builder et paramètres nommés. Si vous utilisez des requêtes raw (nativeQuery dans JPA, rawQuery dans Room), la protection ne fonctionne pas — vous devez passer les paramètres via des expressions préparées, pas par concaténation de chaînes.

Qu'est-ce que Second-Order SQL Injection ?

Second-Order SQL Injection est une attaque où des données malveillantes sont stockées dans la base de données comme sûres, mais sont ensuite utilisées dans une autre requête sans échappement. Par exemple, un attaquant s'inscrit avec un nom d'utilisateur comme ' OR '1'='1. Les données sont sauvegardées comme une chaîne — il n'y a pas d'attaque lors de l'inscription. Mais si une autre requête utilise le nom d'utilisateur dans SQL sans paramétrisation, l'injection se déclenche.

NoSQL Injection peut-il être plus dangereux que SQL Injection ?

NoSQL Injection peut être potentiellement plus dangereux en raison de la moindre sensibilisation des développeurs. Les développeurs connaissent SQL Injection et la plupart utilisent l'ORM, mais peu connaissent NoSQL Injection. Dans MongoDB, une requête mal formée peut retourner tous les documents d'une collection. La protection est la même — prepared statements (paramétrisation BSON) et validation stricte des entrées.

Résumé

  • SQL Injection — une attaque qui injecte du code SQL via des paramètres utilisateur non échappés dans les requêtes à la BD
  • Types principaux — In-band (classique), Blind (aveugle, basée sur le temps), Out-of-band (via canal externe)
  • Paramétrisation des requêtes — la seule méthode 100% fiable de protection contre SQL Injection
  • Mythe de l'ORM — l'ORM protège uniquement lors de l'utilisation de méthodes intégrées ; les requêtes raw avec concaténation restent vulnérables
  • Principe du moindre privilège — limiter les privilèges du compte BD minimise les dommages en cas d'attaque réussie
  • Tests réguliers — sqlmap, OWASP ZAP, SonarQube doivent faire partie du pipeline CI/CD
  • SQLite locale — les applications mobiles doivent également paramétrer les requêtes à la base de données locale

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi