Formation Injections SQL


Cette formation est une introduction à la sécurité web : comment fonctionne le web, où se trouvent les failles, et un premier tour des injections, en particulier les injections SQL.

Pourquoi la sécurité web ?

Le web est présent à toutes les échelles :

  • personnelle ;

  • collective, jusqu'au niveau mondial.

Et dans toute la société : politique, entreprises, particuliers…

Ce qui est en jeu, ce sont des données (mots de passe, etc.), mais aussi l'image d'un site (le deface, qui consiste à modifier l'apparence d'un site piraté) et bien d'autres choses.

« Ça ne nous arrivera jamais, on est trop peu connus. »

Un dirigeant d'entreprise qui mériterait d'être viré

Comment ça marche ?

Le web repose sur des requêtes : un client envoie une requête à un serveur, qui renvoie une réponse.


La requête HTTP

Une requête HTTP est composée de trois parties :

  • la ligne de requête : la méthode et le chemin (path) ;

  • les en-têtes (headers) : attributs, cookies… ;

  • le corps (body), vide dans l'exemple ci-dessous.

GET /wp-content/uploads/2017/11/cfai84.jpg HTTP/2
Host: www.flexgrid.fr
Accept-Language: en-US,en;q=0.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.71 Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Referer: https://www.root-me.org/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

La réponse

La réponse a la même structure :

  • la ligne de statut : le protocole et le code de réponse ;

  • les en-têtes ;

  • le corps, ici une page HTML.

HTTP/2 301 Moved Permanently
Date: Tue, 12 Nov 2024 20:39:11 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 234
Location: http://www.capenergies.fr/
Server: o2switch-PowerBoost-v3

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
  <head>
    <title>301 Moved Permanently</title>
  </head>
  <body>
    <h1>Moved Permanently</h1>
    <p>The document has moved <a href="http://www.capenergies.fr/">here</a>.</p>
  </body>
</html>

Manipuler une requête

Pour construire et modifier des requêtes, on peut utiliser :

  • curl, en ligne de commande ;

  • le navigateur (et ses outils de développement) ;

  • Burp Suite, un proxy qui permet d'intercepter et de modifier les requêtes.

Client vs serveur

Le serveur

  • C'est la machine physique qui héberge le serveur.

  • Il traite les requêtes reçues et envoie les réponses.

  • Logiciels possibles : Apache, NGINX.

  • Langages côté serveur : Node.js, Python, PHP, Ruby on Rails…

Le client

  • C'est un navigateur, un script ou un logiciel qui envoie des requêtes.

  • Il observe et interprète les réponses.

  • Langages côté client : HTML, CSS, JavaScript (et Python pour les scripts).

Le hacking web

Les failles peuvent venir de plusieurs endroits :

  • les défauts de développement ;

  • les vulnérabilités non patchées :

    • mises à jour manquantes ;

    • failles 0 day ;

  • les mauvaises configurations :

    • accès non autorisés ;

    • …

  • la récupération de requêtes :

    • mauvais chiffrement ;

    • Man In The Middle ;

    • …

  • et bien d'autres.

Les attaques visent soit le serveur (exemple : l'injection SQL), soit le client (exemple : le XSS).

Les injections

L'OWASP (Open Worldwide Application Security Project) est un projet open source ouvert à tout le monde. Il publie notamment un classement des risques les plus courants, le Top 10.

Les injections en font partie : elles touchent 94 % des applications testées.

Le principe : on envoie une requête contenant du code malveillant que l'application traite comme du code.

Injection côté client

Le client envoie une requête contenant du code malveillant. Le serveur le renvoie en partie, et il est exécuté à travers le client qui le reçoit.

Exemple (XSS) :

  1. L'attaquant poste sur un forum un message contenant un script.

  2. Nicolas lit le message : son navigateur interprète le script.

  3. Le script renvoie Nicolas vers le serveur de l'attaquant, avec ses cookies d'authentification.

  4. L'attaquant récupère les cookies de Nicolas dans la requête reçue, et peut ainsi se faire passer pour lui.

Injection côté serveur

Le client envoie une requête contenant du code malveillant. Le serveur traite ce code et renvoie des informations en conséquence, ou modifie ses données internes.

Le cas des injections SQL

Prenons un formulaire de connexion :

  1. L'utilisateur envoie une requête de connexion avec ses identifiants.

  2. Le serveur utilise ces identifiants pour construire une requête vers sa base de données.

  3. La base de données répond.

  4. S'il y a une réponse, l'utilisateur peut se connecter.

Voici la table des utilisateurs :

ID

username

password

1

admin

adminpasswrd

2

jeanne

(fj&5b+.&é"'k45q

3

xX_jean_Xx

1234password

Et le code du serveur qui construit la requête :

$query = "SELECT * FROM users WHERE password = '$pass' AND username = '$name'";

Les valeurs saisies par l'utilisateur sont insérées telles quelles dans la requête : c'est ce qui rend l'injection possible.

Quelques notions de SQL

  • -- (tiret, tiret, espace) : le reste de la ligne est un commentaire.

  • <requête> UNION <autre requête> : renvoie les résultats des deux requêtes.

  • On peut aussi exploiter d'autres conditions : le temps de réponse, la réponse du serveur, etc.

Pour aller plus loin : la cheatsheet PortSwigger sur les injections SQL.

Ce tutoriel explique le développement côté serveur, l’ensemble des SQLi ainsi que les moyens de s’en prévenir https://zestedesavoir.com/tutoriels/945/les-injections-sql-le-tutoriel/.

Pour approfondir les bonnes pratiques de code, ce site explique en détail les requêtes préparées https://phptherightway.com/#databases (concepts valables pour Python).

La syntaxe diffère entre MySQL et les autres bases de données, mais le principe reste le même:
si la requête n’est pas interne (i.e si elle dépend d’une entrée/input utilisateur au niveau du site zeb), alors on la construit en 2 temps en validant d’abord l’entrée utilisateur avant d’éxécuter l’ensemble.


Pour voir tout cela en détail:

À noter pour les plus curieux que les PDO/requêtes préparées ne sont pas infaillibles. Ce sont des fonctions codées la plupart du temps en C, donc certaines techniques utilisant le null byte (terminant une chaîne de caractères) peuvent en venir à bout:

https://www.slcyber.io/assetnote-security-research-center/a-novel-technique-for-sql-injection-in-pdos-prepared-statements

Pratique !