Vous êtes sur la page 1sur 9

FICHE SAVOIRS

LES INJECTIONS SQL ET NOSQL

Contenu
1. Les failles d’injection dans les applications web������������������������������������������������������������������������������������� 1
2. Les injections SQL������������������������������������������������������������������������������������������������������������������������������������� 1
3. Les injections NoSQL�������������������������������������������������������������������������������������������������������������������������������� 4
4. Détection et protection������������������������������������������������������������������������������������������������������������������������������ 6
5. En synthèse������������������������������������������������������������������������������������������������������������������������������������������������ 8
6. Références complémentaires������������������������������������������������������������������������������������������������������������������� 8

1. Les failles d’injection dans les applications web


Dans une application web, on utilise des champs ou des formulaires HTML comme composants permettant
la saisie de l’utilisateur. Ces champs sont généralement la cible d’injections. Par exemple, si vous tapez
un nom d'utilisateur et un mot de passe dans des champs d’authentification, ils seront ensuite envoyés à
la base de données pour pouvoir vous authentifier. Si ces données ne sont pas suffisamment contrôlées,
un pirate peut s’en servir pour faire exécuter d’autres traitements au serveur.
Une faille d’injection résulte donc d’une mauvaise sécurisation des traitements, permettant à un
attaquant de tirer profit d’une entrée utilisateur pas suffisamment protégée et assainie pour faire
exécuter des commandes malveillantes ou d'accéder à des données non autorisées.
On distingue différentes familles d’injection en fonction du protocole visé (SQL, XML,XPATH, LDAP) ou
du type d’injection : injections SQL, injections de code, injections de commandes…
Les injections peuvent entraîner des conséquences graves, puisqu’elles peuvent mener à la perte ou
corruption de données et au déni d’accès au service, jusqu’au contrôle total du serveur par l’attaquant.

2. Les injections SQL


Le type d'attaque par injection le plus connu est l'injection SQL (SQLi).
De nombreuses applications web travaillent autour d'un système de gestion de base de données
(SGBDR) et comportent des formulaires qui attendent des données fournies par les utilisateurs. Si
le développeur ne travaille que sur les scénarios attendus de saisies des données, il risque de ne pas
intégrer de contrôles de validation (input validation) ce qui peut entraîner une sensibilité à l'injection.

CNED – BTS SIO – Fiche savoirs 1


Dessin humoristique sur l’utilisation d’injection https://xkcd.com/327/

Dans le cas d’une attaque par injection SQL, par exemple au lieu de mettre un nom d'utilisateur et un
mot de passe sur une page de connexion, un utilisateur malveillant entrera des données directement
interprétées par le moteur SQL, ce qui lui permettra de modifier le comportement de votre application.

Exemple de saisie avec et sans injection et traitement sur les serveurs Apache puis MySQL.

Dans l’image ci-dessus, lors de la saisie de l’identifiant et du mot de passe associé, le serveur Apache
exécute une requête après du serveur MySQL en substituant directement aux variables $_GET[‘login’]
et $_GET[‘password’] le contenu des champs textes saisis par l’utilisateur.
Dans le cas d’une saisie non malveillante comme à gauche de l’image, la requête envoyée au serveur est :

SELECT id, login FROM users WHERE login = ‘admin’ AND password = ‘secret’

Si le serveur MySQL trouve un utilisateur existant avec ces 2 informations, elle va renvoyer au serveur
Apache son id et son login. Sinon, elle ne renverra rien.

CNED – BTS SIO – Fiche savoirs 2


Dans le cas de droite, une saisie malveillante contenant une injection SQL avec une instruction
conditionnelle (l’emploi du « OR » entre les deux conditions), la requête composée par Apache sera
donc :

SELECT id, login FROM users WHERE login = ‘X’ OR ‘1’=’1’ AND password = ‘X’ OR
‘1’=’1’

Dans cette requête, le serveur MySQL, au lieu de renvoyer l’utilisateur qui répond à la condition (bon
login et bon mot de passe), va renvoyer tous les utilisateurs de la table users puisque les conditions
‘1’=’1’ renverront toujours vrai.

2A. Risques
À travers une injection SQL il est possible de :
— récupérer des données (comptes utilisateurs, cartes bancaires, etc.). On parle alors souvent de vols
de données dans l'actualité. C'est l'utilisation la plus courante ;
— contourner une authentification : on s'authentifie sur une application sans avoir des identifiants
valides ;
— ajouter et/ou modifier des données : par exemple pour ajouter un compte administrateur, ou
modification d'un compte existant pour ajouter des privilèges ;
— supprimer des informations, ou vider la base de données : si une personne a une dent contre une
entreprise, ou juste pour embêter son monde. C'est l'utilisation la moins courante ;
— exécuter des commandes systèmes : ça permet d'avoir plus d'informations sur la machine, lancer
des attaques à distance, installer des programmes, etc. ;
— escalader les privilèges pour augmenter le niveau d'accès d'un utilisateur à la machine, et finalement
avoir l'accès total : administrateur ou root ;
— réaliser un déni de service (DoS) : en saturant le serveur ce qui rend le site très lent et donc
inaccessible ;
— lire un fichier : et donc voir le code source d'une application.

2B. Types d’injections


Il existe plusieurs types d'injection SQL avec un degré de complexité différent :

CNED – BTS SIO – Fiche savoirs 3


Les injections SQL simples : « Union based » et « Error based »
Il s'agit des injections les plus simples et les plus faciles à détecter, il n'y a aucune ou peu de
protections. L'exemple le plus courant est le formulaire d'authentification.
Les attaques « Union based » utilisent le mot-clé UNION du langage SQL pour adjoindre une autre
requête à la requête exécutée :

SELECT * FROM ARTICLES WHERE published = 1 AND category = 'Sécurité' UNION SELECT
1,username,password,4,5 FROM USERS

Avec cette requête, l'utilisateur aura la liste d'article de la catégorie « Sécurité » mais aussi la liste des
comptes utilisateurs et leur mot de passe.
Les attaques « Error based » se basent sur le fait que les erreurs SQL sont affichées sur la page et en
partie interprétées. Il est donc possible de faire afficher les informations souhaitées dans les erreurs.

Les injections SQL Blind : « Boolean based » et « Time based »


Ces attaques cherchent à obtenir des informations à l'aveugle en tâtonnant.
Dans le cas des injections « Boolean based », on cherche à extraire des informations avec la base de
données en exploitant ses réponses à un envoi massif de requêtes dont la réponse est binaire : vrai ou
faux.
Les injections « Time based » exploitent le temps de réponse du serveur pour deviner les réponses au
dialogue en estimant que si la requête prend plus de temps à obtenir une réponse, c’est qu’elle est vraie.
Ces deux techniques nécessitent des outils pour tester un nombre massif de requêtes sur le serveur.

3. Les injections NoSQL


Considérer que les sites utilisant des bases de données dites « NoSQL » (MongoDB, Cassandra, Neo4j,
Oracle NoSQL, ...) sont plus sécurisés que ceux utilisant des SGBDR est une idée fausse. Ces sites
sont tout autant vulnérables mais simplement actuellement moins attaqués par les robots car moins
répandus (moins de 20% des sites), ce qui donne lieu à cette fausse croyance.
Cependant, étant donné qu’en noSQL les enregistrements ne suivent pas une structure commune, la
découverte lors d’une injection de la structure d’une donnée spécifique ne garantit pas son exploitation
facile sur d’autres données.
Ces bases de données s’éloignent du modèle relationnel classique et exploitent une autre manière de
réaliser des requêtes. Par exemple, MongoDB utilise un format basé sur le standard JSON comme
structure de requête.
Pour effectuer une requête d’interrogation en php, on va alors construire un tableau associatif (clé :
valeur) contenant les paramètres et passer ensuite ce tableau à des méthodes de la classe MongoClient
comme find(), findOne(), …
Cette différence de langage ne permet donc pas d’exploiter les injections SQL traditionnelles. Cependant,
comme leurs cousines SQLi, les injections NoSQL exploitent donc des défauts de développement au
niveau de ces requêtes pour exécuter des injections inhérentes à cette syntaxe.
On trouve deux types d’exploitations de vulnérabilités en NoSQL :
• Les injections d’opérateur : c’est le cas le plus courant, qui exploite les défauts de validation des
entrées utilisateur sur une requête en injectant des opérateurs afin d’altérer le comportement de la
requête initialement prévue par le développeur.

CNED – BTS SIO – Fiche savoirs 4


• Les injections de code JavaScript : dans le cas de l’utilisation d’une entrée utilisateur au sein d’un
opérateur faisant appel à une fonction JavaScript, il est également possible d’injecter du code JavaS-
cript au sein de l’environnement Mongo.
Comme pour les injections SQLi, les stratégies de détection des vulnérabilités d’injection sont basées
sur l’ajout de code générant une erreur d’exécution mongodb en espérant avoir un affichage d’erreur
montrant que l’entrée est vulnérable (injection « Error based »), l’ajout d’opérateur booléen (injection «
Boolean based ») ou l’ajout de code induisant un délai calculé (injection « Time based »). Si l’affichage de
réponse à la requête réagit en tenant compte de l’injection, la faille est exploitable.

Exemple d’injection d’opérateur booléen


Ce type d’injection permet d’exploiter un défaut de vérification des entrées utilisateur, en particulier du
type de données fournies par l’utilisateur, au sein des requêtes Mongo.

if (isset($_POST['usr_name']) && isset($_POST['usr_password'])) {


$usr_name = ($_POST['usr_name']);
$usr_password = ($_POST['usr_password']);
$con = new MongoClient(); // Connexion a MongoDB

// Si la connexion a fonctionné on effectue la requête de recherche


if ($con) {
$db = $con->test;
$people = $db->people;
$qry = array(
"user" => $usr_name,
"password" => $usr_password
); // Construction du tableau pour la requête NOSQL
$result = $people->findOne($qry); // Exécution de la requête avec les données
du tableau (ici recherche de l'utilisateur avec le login et mot de passe fournis
en POST)

// Si les identifiants correspondent on connecte l'utilisateur


if ($result) {
echo "Bienvenue Administrateur"; // Zone Admin
exit(0);
}
}
else {
die("Mongo DB not installed");
}
}

Extrait d’un script basique d’authentification vulnérable en php avec MongoDB.


Dans ce script, on récupère en POST des données contenant le login et le mot de passe de connexion.
On crée un tableau associatif contenant ces 2 données puis on exécute la requête de recherche d’un
utilisateur en fournissant ce tableau $qry à la méthode MongoDb findOne($qry).

Dans le cas du script d’exemple, si au lieu des données du formulaire, on envoie en POST la chaine de
valeurs suivante :

usr_name[$ne]=h4cker&usr_password[$ne]=h4xor

CNED – BTS SIO – Fiche savoirs 5


Le tableau associatif généré contiendra des informations permettant d’executer une autre requête que
celle prévue par les développeurs :

array (size=2) array (size=2)


'user' => string 'h4cker' 'user' =>
(length=6)
array (size=1)
'password' => string 'h4xor'
'$ne' => string 'h4cker'
(length=5)
(length=6)
'password' =>
array (size=1)
'$ne' => string 'h4xor'
(length=5)

Tableau associatif normalement généré Tableau associatif généré par l’injection

En langage mongoDB L’opérateur $ne correspond à "Différent de". L’execution $people->findOne($qry)


exécutera alors un équivalent en "Pseudo SQL" d’un "WHERE user!=h4cker and password!=h4xor" ce qui
permettra d’usurper l’authentification.

4. Détection et protection
4A. Détection et audit
Il est possible de trouver des points d'injection SQL un peu partout (URL, formulaires, cookies, Ajax, etc.)
et il est nécessaire de faire de nombreux tests pour savoir s'il s'agit d'un point d'injection viable ou non.
Les tests courants consistent à tester manuellement l’ajout de caractères spéciaux dans un champ
input :
— ' ou %27 : le single quote ou sa forme en URL encode ;
— " ou %22 : le double quote ou sa forme en URL encode ;
— 1' or '1'='1 : une seconde condition toujours vraie (test très utilisé dans les formulaires
d’authentification) ;
— admin'-- ou admin' # ou admin' /* suivi d’une nouvelle requête ;
— 1+1 pour voir si le résultat et interprété…

Les vulnérabilités NoSQL sont détectables de la même façon en injectant des éléments susceptibles de
modifier la requête exécutée dans les champs input ou dans les données GET et POST transmises (via la
barre d’adresse ou via un forgeage de requêtes GET et POST).

Il existe également de nombreux outils automatisés, permettant la détection et l'exploitation d'injections


SQL lors d'audits de sécurité. Par exemple :
— SQLMap : outil le plus connu d'automatisation de détection et d'exploitation d'injection SQL ;
— Nikto : outil d'audit d'application web qui trouve tout seul les points d'injection et les failles associés ;
— Nessus : scanner de vulnérabilité propriétaire très connu ;
— et bien d'autres (wapiti, w3af, etc.).
L’équivalent existe aussi pour les injections NoSQL :
— NoSQLMap : petit utilitaire open source basé sur Python, capable d'auditer pour trouver une mauvaise
configuration et automatiser les attaques par injection. Il prend en charge les bases de données
suivantes : MongoDB, CouchDB, Redis et Cassandra ;

CNED – BTS SIO – Fiche savoirs 6


— Mongoaudit : outil spécifique pour les bases MongoDB. Il permet d’effectuer des pentests pour
trouver un bogue, une mauvaise configuration et des risques potentiels sur une application.

4B. Protéger les applications contre les injections SQL et NoSQL


Il est possible de sécuriser les sites web contre ce type d’injections en renforçant dans le code de
l’application les contrôles effectués sur les données entrantes.
Pour contrer les injections SQL, il est recommandé de :
— toujours vérifier et assainir les informations entrées par l'utilisateur. En PHP par exemple,
l'utilisation de la fonction « mysqli_real_escape_string() » est incontournable ;
— utiliser les procédures stockées : ce sont des routines sur le SGBD qui constituent une aide pour
lutter contre les injections SQL en plus du gain de performance apporté ;
— utiliser des requêtes préparées : la requête sera analysée, compilée et optimisée avant d'insérer les
paramètres. Elles apportent souvent un gain de performance aussi ;
— utiliser des expressions régulières pour filtrer les informations entrées par l'utilisateur. Par
exemple, s’il y a les mots-clés « union, select » on renvoie vers une page par défaut (erreur ou autre) ;
— gérer les droits de connexion à la base de données : mettre uniquement les droits nécessaires, voire
créer plusieurs profils en fonction des besoins ;
— gérer les messages d'erreur : il est important de ne jamais afficher les messages d'erreurs sur
l'environnement de production. Il vaut mieux les journaliser dans des fichiers de logs ;
— gérer les droits des fichiers : il faut vérifier les droits des fichiers de l'application, pour éviter qu'il
soit possible de les lire à l'aide d'une injection SQL ;
— journaliser les requêtes exécutées : en cas d'attaque, les fichiers de logs (serveur et applicatif)
constituent votre meilleur allié pour trouver rapidement le point d'injection et prendre les mesures
adéquates. Il faut également les archiver régulièrement pour être sûr qu'ils ne soient pas effacés ;
— gérer les accès au serveur de base de données : vérifiez quelles applications accèdent à la base de
données et leurs sécurités respectives ;
— séparer les environnements : si possible, il est conseillé de séparer la machine hébergeant la base
de données de la machine hébergeant le site web. C'est plus facile à maintenir, à superviser et si la
machine du site web est piratée, celle de la base de données ne l'est pas ;
— utiliser un ORM : de nombreux langages disposent d'outils ORM (Object Relational Mapper) qui peuvent
obfusquer les requêtes, c’est-à-dire masquer leur syntaxe ;
— utiliser l’API OWASP : l'organisation OWASP dispose d'une API appelée the OWASP Enterprise Security
API (ESAPI) qui peut être utilisée pour sécuriser vos applications web.
Afin de se prémunir contre les injections NoSQL, les conseils sont du même ordre :
— vérifier les entrées utilisateur, en particulier le type, afin d’empêcher un utilisateur malveillant
d’injecter des objets JSON au sein de requêtes MongoDB ;
— utiliser des requêtes ne faisant pas intervenir la fonctionnalité d’exécution de code JavaScript
(telle que $where, $function, $accumulator, group et mapReduce) lorsque celles-ci manipulent des
données provenant d’entrées utilisateur ;
— Désactiver le moteur JavaScript de MongoDB :
- en lançant le programme mongo avec l’option –noscripting
- en mettant la valeur du paramètre security.javascriptEnabled à false.

CNED – BTS SIO – Fiche savoirs 7


5. En synthèse
— Les injections permettent de manipuler les entrées pour effectuer des actions non autorisées et
accéder à des données confidentielles.
— Les conséquences d’une injection peuvent être très graves  : fuite de données sensibles,
compromission de ces données, déni de service…
— Les injections peuvent inclure des commandes SQL, NoSQL, JavaScript, HTML ou OS.
— On peut prévenir les attaques par injection en sécurisant le code d’une application avec la validation
des entrées, des variables paramétrées, l’utilisation d’un ORM ou des procédures SQL stockées.

6. Références complémentaires
Article intéressant de l'OWASP :
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
Comment se protéger des injections SQL d'après php.net :
http://php.net/manual/fr/security.database.sql-injection.php
Les requêtes préparées et les procédures stockées par php.net :
http://php.net/manual/fr/pdo.prepared-statements.php
Article intéressant concernant les avantages des procédures stockées :
http://www.dbnewz.com/2010/12/08/pour-ou-contre-les-procedures-fonctions-stockees/
Une liste tenue à jour des attaques par injection SQL :
http://codecurmudgeon.com/wp/sql-injection-hall-of-shame/
Article très sympa à lire décrivant de nombreux scenarii analysés :
http://christianelagace.com/wordpress/comment-les-hackers-reussissent-les-injections-sql/
Documentation des opérateurs MongoDB :
https://www.mongodb.com/docs/manual/reference/operator/query/
NoSql Injection Cheatsheet :
https://nullsweep.com/nosql-injection-cheatsheet/

CNED – BTS SIO – Fiche savoirs 8


Les cours du CNED sont strictement réservés à l’usage privé de leurs destinataires et ne sont pas destinés à une utilisation collective.
Les personnes qui s’en serviraient pour d’autres usages, qui en feraient une reproduction intégrale ou partielle, une traduction sans
le consentement du CNED, s’exposeraient à des poursuites judiciaires et aux sanctions pénales prévues par le Code de la propriété
intellectuelle. Les reproductions par reprographie de livres et de périodiques protégés contenues dans cet ouvrage sont effectuées
par le CNED avec l’autorisation du Centre français d’exploitation du droit de copie (20, rue des Grands-Augustins, 75006 Paris).
CNED, BP 60200, 86980 Futuroscope Chasseneuil Cedex, France
© CNED 2022 87D32TEWB5322

Vous aimerez peut-être aussi