08/01/2025
1
L’injection SQL
Sécurité des applications Web
Présenté par : © Nissen MASMOUDI
AU : 2024-2025
L'injection SQL
2
C’est quoi l’injection SQL ?
L'injection SQL (SQL Injection) est une technique d'attaque utilisée pour exploiter des
vulnérabilités dans une application web qui interagit avec une base de données.
Cette attaque se produit lorsque des données fournies par l'utilisateur sont interprétées
comme une partie d'une commande SQL au lieu d'être traitées comme des données.
Cela permet à un attaquant
d'exécuter des commandes SQL non
prévues, potentiellement
destructrices, sur la base de données.
L'injection SQL
1
08/01/2025
3 Mécanisme d'une Injection SQL
Les Entrées Non Validées :
• Une application web demande des données à l'utilisateur (comme un identifiant, un
mot de passe, ou des informations via un formulaire HTML).
• Si les données fournies par l'utilisateur ne sont pas correctement validées ou
échappées, elles peuvent être insérées directement dans une requête SQL.
Exploitation : Un attaquant injecte du code SQL malveillant à travers les champs de
saisie ou les paramètres de requêtes HTTP pour modifier le comportement de la
requête SQL.
L'injection SQL
4 Mécanisme d'une Injection SQL
Impact :
• Lecture de données sensibles (par exemple, mots de passe, numéros de carte de
crédit).
• Modification ou suppression des données.
• Prise de contrôle de la base de données (exécution de commandes
d'administration).
• Escalade d'accès à l'ensemble du serveur.
L'injection SQL
2
08/01/2025
Types d'Attaques par Injection SQL
5
Injection SQL Basique : Lire, modifier ou supprimer des données. Exemple :
SELECT * FROM users WHERE id = 1 OR 1=1;
Blind SQL Injection :
o Exploiter une application sans voir directement le résultat des requêtes. Par
exemple Tester des conditions logiques pour obtenir des réponses booléennes.
Scénario 1 : L'attaquant teste avec une requête comme :
[Link] AND 1=1 SQL généré SELECT * FROM users WHERE id = 1 AND 1=1;
Scénario 2 : Si la page se charge normalement, cela indique que l'injection est possible. Il teste alors avec :
[Link] AND 1=2 SQL généré SELECT * FROM users WHERE id = 1 AND 1=2;
L'injection SQL Si la page affiche un message d'erreur ou un résultat vide,
l'attaquant sait que l'injection est possible.
Types d'Attaques par Injection SQL
6
Union-Based SQL Injection : Ajouter une autre requête SQL avec UNION pour
extraire des données d'autres tables.
SELECT name FROM users WHERE id = 1 UNION SELECT credit_card_number FROM credit_cards;
Error-Based SQL Injection :
• Objectif : Forcer l'application à générer des messages d'erreur contenant des
informations sur la base de données.
• Exemple :
SELECT * FROM users WHERE id = 1 AND (SELECT 1/0); -- provoque une division par zéro
L'injection SQL
3
08/01/2025
Exemples d’attaque injection SQL
7 CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
Soit la table User défini comme suit:
username VARCHAR(50),
On dispose les enregistrements suivants : password VARCHAR(255));
INSERT INTO users (username, password) VALUES ('admin', '12345'), ('user', 'password');
La requête non sécurisée se présente dans le code PHP par exemple comme suit :
$sql = "SELECT * FROM users WHERE username = '" . $_POST['username'] . "' AND password = '" . $_POST['password'] . "'";
Exploitation : L’attaquant entre dans le champ « username » et saisit les données suivantes :
' OR 1=1 -- L'attaquant contourne
l'authentification et
accède aux données.
La requête devient :
SELECT * FROM users WHERE username = '' OR 1=1 --' AND password = '';
L'injection SQL
Exemples d’attaque injection SQL
8
Une requête SQL comme celle-ci pour vérifier un utilisateur dans un script de connexion :
SELECT * FROM users WHERE username = '$_POST[username]' AND password = '$_POST[password]';
Si un utilisateur malveillant entre les valeurs suivantes dans les champs du formulaire :
o Nom d'utilisateur : admin' --
o Mot de passe : anything
La requête devient :
SELECT * FROM users WHERE username = 'admin' --' AND password = 'anything';
Le -- transforme le reste de la ligne en commentaire, ce qui signifie que la condition sur le mot de
passe est ignorée. SiSQLl'utilisateur admin existe, l'attaquant peut accéder sans mot de passe.
L'injection
4
08/01/2025
Protection contre une attaque injection SQL
9
Requêtes Paramétrées (Prepared Statements) : Utilisez des requêtes paramétrées qui séparent
le code SQL des données utilisateur:
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);$stmt->execute();
Validation des données : <?php
$email = $_POST['email’]; // Entrée utilisateur
• Validez les entrées utilisateur en fonction du contexte. Par exemple, on peut utiliser la fonction
// Valider avec filter_var
filter_var pour valider un email en PHP :
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "L'email est valide.";
} else {
echo "L'email n'est pas valide.";
L'injection SQL }
?>
Protection contre une attaque injection SQL
10
Validation des données (suite) :
On peut valider un email directement côté client avec un attribut HTML5 :
<form method="POST" action="votre_script.php">
<label for="email">Email :</label>
<input type="email" id="email" name="email" required>
<button type="submit">Envoyer</button>
</form>
Le champ type="email" garantit qu'un format valide est requis avant soumission.
L'injection SQL
5
08/01/2025
Protection contre une attaque injection SQL
11
Échappement ou élimination des caractères spéciaux :
Il est important pour empêcher des attaques comme l'injection HTML ou l'injection SQL.
• on peut utiliser htmlspecialchars ou htmlentities pour éliminer les caractères spéciaux avant de
les afficher. <?php$nom = $_POST['nom']; // Entrée utilisateur
// Échapper les caractères spéciaux
<script>alert('hacked!')</script>
$nom_securise = htmlspecialchars($nom, ENT_QUOTES, 'UTF-8’);
// Empêche les attaques XSS
<script>alert('hacked!')</script>
echo "Bonjour, $nom_securise !";?>
• Voici un exemple d’un formulaire utilisant htmlspecialchars :
<form method="POST" action="[Link]">
<label for="nom">Nom :</label>
<input type="text" id="nom" name="nom" value="<?php echo htmlspecialchars($nom, ENT_QUOTES, 'UTF-8'); ?>" required>
<button type="submit">Envoyer</button>
</form> L'injection SQL
Protection contre une attaque injection SQL
12
// Lors de l'inscription
$hashed_password = password_hash($password_input, PASSWORD_DEFAULT);
Hachage des Mots de Passe : // Stocker $hashed_password dans la base de données
// Lors de la connexion
• Jamais stocker les mots de
$stmt = $conn->prepare("SELECT password FROM users WHERE username = ?");
passe en clair dans la base de $stmt->bind_param("s", $username_input);$stmt->execute();
données. $stmt->bind_result($hashed_password);
if ($stmt->fetch()) {
• En PHP, on peut utiliser par les if (password_verify($password_input, $hashed_password)) {
fonctions de hachage $_SESSION['loggedin'] = true;
header("Location: [Link]");
sécurisées password_hash() et
exit;
password_verify() pour vérifier } else {
les mots de passe. $error = 'Nom d\'utilisateur ou mot de passe incorrect’;
}
} else {
L'injection SQL $error = 'Nom d\'utilisateur ou mot de passe incorrect’;
}
6
08/01/2025
Protection contre une attaque injection SQL
13
Limiter les Privilèges : Donnez à l'utilisateur de base de données de l'application des privilèges
minimums nécessaires.
CREATE USER app_user IDENTIFIED BY app_password;
-- Autoriser l'utilisateur à se connecter
GRANT CREATE SESSION TO app_user;
-- Accorder des privilèges sur des tables spécifiquesGRANT SELECT, INSERT, UPDATE, DELETE
ON schema_name.table_name TO app_user;
-- Si plusieurs tables sont nécessaires
GRANT SELECT, INSERT, UPDATE, DELETE ON schema_name.other_table TO app_user;
L'injection SQL
Protection contre une attaque injection SQL
14
Filtrage d'Entrées : Filtrer les entrées utilisateur pour interdire les mots-clés suspects (SELECT,
Exemple 1 : Entrée valide try {
UNION, --, etc.)
$safeInput = validateInput('Nom utilisateur’);
function validateInput($input) {
echo "Entrée validée : " . $safeInput;
// Liste des mots-clés suspects à rechercher
} catch (Exception $e) {
$pattern = '/\b(SELECT|UNION|--|INSERT|DELETE|UPDATE|DROP)\b/i';
echo "Erreur : " . $e->getMessage();
// Vérification de l'entrée utilisateur
}
if (preg_match($pattern, $input)) {
throw new Exception('Entrée invalide : mot-clé suspect détecté.’); Résultat Entrée validée : Nom utilisateur
}
return htmlspecialchars($input, ENT_QUOTES, 'UTF-8’);
} try {
$safeInput = validateInput('SELECT * FROM users’);
Exemple 2 : Entrée contenant un mot-clé suspect
echo "Entrée validée : " . $safeInput;
} catch (Exception $e) {
Erreur : Entrée invalide
L'injection SQL : mot-clé suspect détecté. echo "Erreur : " . $e->getMessage();
}
7
08/01/2025
Démo d’une application
15
attaque via l’injection SQL
Une requête SQL comme celle-ci pour vérifier un utilisateur dans un script de connexion :
SELECT * FROM users WHERE username = '$_POST[username]' AND password = '$_POST[password]';
Si un utilisateur malveillant entre les valeurs suivantes dans les champs du formulaire :
o Nom d'utilisateur : admin' --
o Mot de passe : anything
La requête devient :
SELECT * FROM users WHERE username = 'admin' --' AND password = 'anything';
Le -- transforme le reste de la ligne en commentaire, ce qui signifie que la condition sur le mot de
L'injection SQL
passe est ignorée. Si l'utilisateur admin existe, l'attaquant peut accéder sans mot de passe.
16 Bonnes pratiques
1. Hachage des mots de passe : jamais stocker les mots de passe en texte clair dans
la base de données.
o Comme exemple password_hash() pour hacher les mots de passe lors de leur
insertion et password_verify() pour les vérifier lors de la connexion.
// Hacher le mot de passe avant insertion
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// Vérifier le mot de passe
if (password_verify($password, $row['password']))
{
// Authentification réussie
…
L'injection SQL }
8
08/01/2025
17 Bonnes pratiques
2. Utiliser des bibliothèques ORM : utiliser des outils comme Doctrine ou Eloquent pour
gérer les interactions avec la base de données de manière sécurisée.
3. Limiter les tentatives de connexion : implémenter un système de verrouillage après
plusieurs tentatives échouées pour réduire les risques de force brute.
4. Validation des entrées utilisateur : s’assurer que toutes les entrées utilisateur sont
validées et nettoyées pour correspondre au format attendu.
L'injection SQL