Sécurité des applications Web - Menaces et contre-mesures

Auteur: Mohamed CHINY Durée necessaire pour le cours de Sécurité des applications Web - Menaces et contre-mesures Niveau recommandé pour le cours de Sécurité des applications Web - Menaces et contre-mesures Supports vidéo non disponibles pour ce cours Exercices de renforcement non disponibles pour ce cours Quiz non disponibles pour ce cours

Page 2: L'injection SQL

Toutes les pages

L'injection SQL (ou faire passer du code SQL inaperçu au sein du code source)

Définition

L'injection SQL est une des attaques les plus classiques qu'elle en est devenue la plus populaire. Son principe est tellement simple mais ingénieux et en 2017, elle parait encore à la tête du TOP 10 d'OWASP.

L'attaque consiste à forger son propre code SQL que l'on soumet au serveur. Ce code là sera mélangé à du code SQL propre à l'application (ou site Web) ce qui conduira au détournement du fonctionnement attendu. Les sites qui peuvent être vulnérables à cette attaque sont ceux qui se basent sur une base de données SQL. Donc si le site ne repose pas sur une base de données, il ne présentera aucun risque vis-à-vis de l'injection SQL.

Quand cette attaque réussit, elle peut avoir des conséquences désastreuses sur le site Web comme par exemple:
  • L'accès à un espace non autorisé via une fausse authentification
  • Suppression des données d'une manière frauduleuse
  • Vol de données confidentielles enregistrées dans la base de données
  • Destruction ou atteinte à l'intégrité de la base de données

Exploitation

L'attaque repose sur l'exploitation des entrées d'un site Web comme les champs de formulaires ou la barre d'URL. Par exemple, quand on demande à l'utilisateur de s'authentifier en entrant un login et un mot de passe, si celui-ci était un pirate aux mauvaises intentions, alors au lieux de saisir du texte normal il saisirait des séquences de codes SQL qu'il soumettrait au serveur. Si le site présente une vulnérabilité à l'injection SQL alors il se peut que le code SQL injecté s'exécute et donne lieu à un comportement inattendu comme avoir accès illégalement à l'espace confidentiel.

Par exemple, imaginez que le code SQL (encapsulé dans d code PHP) qui permet de vérifier si un login et un mot de passe sont valides est le suivant:
select * from table_users where login='$_POST["login"]' and pass='$_POST["pass"]'
Notez que $_POST["login"] et $_POST["pass"] représentent les textes que l'utilisateur a saisi dans les champs de formulaire dédiés à cet effet.

Cette requête SQL retournera toutes les lignes (en général y'en aura qu'une seule) où les champs 'login' et 'pass' contiendront respectivement le login et le mot de passe saisis par le client.

Maintenant imaginez avec moi que l'utilisateur (malhonnête) a saisie dans le champ login la chaine admin' -- , alors notre requête SQL deviendra
select * from table_users where login='admin'--' and pass='$_POST["pass"]'
Et puisque le double tiret (--) constitue un commentaire SQL, tout le code qui le suivra sera ignoré au moment de l'exécution ce qui revient à exécuter le code suivant:
select * from table_users where login='admin'
Et voilà, le code SQL de l'application a été modifié suite à cette injection et ne vérifie plus de mot de passe, il se contente seulement de vérifier si le login vaut admin. Si un tel login existe dans la base de données alors le pirate sera authentifié et accédera à l'espace admin.
Il s'agit là de l'exemple le plus basique d'une injection SQL, mais le pirate peut mettre d'autres codes SQL qui peuvent ordonner d'autres traitements et qui ont toutes les chances de s'exécuter si le serveur présente la vulnérabilité.

Comment s'en protéger?

Au niveau du code PHP

Il existe plusieurs méthodes qui permettent de détourner les tentatives d'injection SQL et je vais citer quelques unes:

Filtrer les entrées de l'utilisateur:

A la base, tout ce que l'utilisateur peut soumettre au serveur est considéré comme contenu étranger et potentiellement hostile. Donc, avant de laisser passer ses entrées, il faut les filtrer. On peut tout simplement échapper les caractères spéciaux contenus dans les chaines de caractères soumises en utilisant des fonctions PHP comme addslashes() ou mysql_real_escape_string(). On peut également appliquer les expressions régulières pour vérifier si la chaine représente un tel motif comme par la fonction preg_match() et aussi vérifier la longueur de la chaine par la fonction strlen().

Utiliser l'objet PDO:

Dans le chapitre dédié à l'objet PDO (PHP Data Object), j'ai mentionné quelques vertus de cet objet. Celui qui nous intéresse ici c'est qu'il apporte une immunité totale contre les injections SQL si on sépare les données du traitement (les requêtes préparées avec les marqueurs interrogatifs ou paramètres nommés).

Faire une authentification en deux temps:

Au lieu de vérifier le login et le mot de passe dans la même requête, on sépare ce traitement en deux. On demande d'abord le login, et si celui-ci est correcte on demande ensuite le mot de passe.

Au niveau de la configuration du serveur

Dans ce cas on fera appel simplement au fichier de configuration du moteur PHP nommé php.ini. Il s'agit d'un fichier texte qui contient un ensemble de directives qui permettent de personnaliser certains aspects du comportement du moteur PHP. Pour cette partie on va tout simplement changer la directive magic_quotes_gpc comme ceci:
magic_quotes_gpc = On
Cette diréctive va tout simplement échapper automatiquement les caractères spéciaux présents dans les chaines de caractères entrantes (qui proviennent des formulaires, barre URL et cookies). Elle agit en fait comme la fonction addslashes() mais d'une manière automatisées.

Notez qu'en PHP il existe la fonction ini_set() qui permet de changer la valeur d'une directive du fichier php.ini au moment de l'exécution d'une manière provisoire. Or, cette fonction ne peut pas agir sur la directive magic_quotes_gpc. Il faut par conséquent changer celle-ci au niveau du système (au niveau du fichier php.ini).
Le fait d'échapper les caractères spéciaux ne suffit pas à contrer les injections SQL, mais aident à mieux s'en protéger. Il faut donc songer à d'autres solutions complémentaires comme celles vues précédemment.