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);
?>
Par Thibaut Pietri
Derniers articles
Les risques de sécurité liés aux métadonnées des photos
14 août 2019 En photographie numérique, les métadonnées sont stockées à l'intérieur d'un fichier JPG et permettent de décrire un certain nombre d'informations complémentaires. Ces métadonnées représentent un risque de sécurité.
Comment vérifier si votre site internet a été piraté ou infecté ?
9 août 2019 Le piratage d'un site web peut parfois ne pas être visible directement avec un navigateur web. En effet le piratage peut avoir des objectifs variés. Certains ont tout intérêt à rester invisible.
L'authentification à facteurs multiples pour protéger votre site web
7 août 2019 L'authentification à facteurs multiples est un système de sécurité combinant au moins deux modes d'identification différents. Explications.
Thibaut 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 6 ans | Répondre