Passer au contenu
C'est quoi une injection SQL ?

C'est quoi une injection SQL ?

10 juillet 2019 attaque  vulnérabilité 

Une injection SQL est un type d'attaque contre un site web qui utilise le langage SQL en l'ajoutant à des paramètres d'entrée d'une page.

Prenons un exemple

Sur votre site, une page nommée exemple.php?id=456 contient des paramètres en entrée comme un numéro d'identifiant d'un enregistrement en base de données.

Votre page exemple.php va ensuite contenir du code SQL qui va chercher les informations dans une base de données qui correspondent à l'identifiant 456.

Exemple :

SELECT * FROM actualites WHERE id='456'

L'attaquant peut utiliser cette porte d'entrée pour transformer la requête ?id=456 en ?id=' OR 1=1

La requête qui va se lancer maintenant sera :

SELECT * FROM actualites WHERE id='' OR 1=1

Le résultat de la page sera alors complètement différent et peut afficher ici l'ensemble des données de votre table actualites.

Cet exemple est bien sur simplifié et les injections SQL peuvent être trés complexes et être utilisées pour différents objectifs comme :

  • Récupérer des données (mot de passe, email...)
  • Modifier des données
  • Supprimer des données
  • Exécuter des commandes systèmes
  • Lire ou écrire sur le système de fichier du serveur

Que faire ?

Développer en utilisant des requêtes préparées, avec la librairie PDO dans le cadre du langage PHP. Et sinon faire appel à SiteProtect.fr pour sécuriser votre site :-)

Même avec PDO le code suivant n'est pas bon car des injections SQL sont possibles avec les variables login et password :

<?php
// On récupère les variables envoyées par le formulaire
$login = $_POST['login'];
$password = $_POST['password'];

// Connexion à la base de données avec PDO
try { $bdd = new PDO('mysql:host=localhost;dbname=bdd','votre-login','votre-mot-de-passe'); }
catch (Exeption $e) { die('Erreur : ' .$e->getMessage())  or die(print_r($bdd->errorInfo())); }

// Requête SQL
$user = $bdd->query("SELECT * FROM utilisateurs WHERE login='$login' AND password='$password'");
?>

Le code suivant est valide car la requête est protégée, les paramètres ne sont pas concaténés mais envoyés séparément :

<?php
// On récupère les variables envoyées par le formulaire
$login = $_POST['login'];
$password = $_POST['password'];

// Connexion à la base de données avec PDO
try { $bdd = new PDO('mysql:host=localhost;dbname=bdd','votre-login','votre-mot-de-passe'); }
catch (Exeption $e) { die('Erreur : ' .$e->getMessage())  or die(print_r($bdd->errorInfo())); }

// Requête SQL sécurisée
$user = $bdd->prepare("SELECT * FROM utilisateurs WHERE login=? AND password=?");
$user->execute(array($login, $password));
?>

La encore cet exemple est simplifié au maximum dans le cadre de cet article. Nous ne parlons pas non plus de hachage des mots de passe qui sont stockés en clair dans ce code.

Une meilleure pratique aurait été de hacher le mot de passe avant de le comparer au mot de passe stocké (en étant haché) en base de données :

<?php
$hash = \password_hash($password, PASSWORD_DEFAULT);
?>
Note : 4.7 - 7 votes Evaluer cet article
4.7

Par Thibaut Pietri

Ingénieur informatique spécialisé réseau, basé à Toulouse, j'ai plus de 20 ans d'expérience en développement et sécurisation de sites Internet, Extranet & applications mobiles autour des technologies LAMP (Linux/Apache/MySQL/PHP) sur différents outils de gestion de contenu (Wordpress, Prestashop, Drupal, Isens Evolution...).

Derniers articles

1 commentaire

  1. Thibaut PietriThibaut Pietri

    A ne pas négliger, les injections SQL représentent encore à ce jour 50% des attaques d'applications web. A voir sur l'article Quelques indicateurs sur la cybersécurité en 2019

    Il y a 5 ans | Répondre

 
Retour en haut de la page