SQL et Sécurité : Prévention de l'Injection SQL et Bonnes Pratiques de Sécurité

Qu'est-ce que l'Injection SQL ?

L'injection SQL est une technique d'attaque où un attaquant insère ou "injecte" une requête SQL malveillante dans une entrée de données d'une application, qui est ensuite exécutée par le système de gestion de base de données (SGBD). Cette faille de sécurité peut être exploitée pour accéder à des données non autorisées, modifier ou supprimer des données, et exécuter des opérations administratives dangereuses.

Exemples d'Injection SQL

Injection via un Formulaire de Connexion

Supposons un formulaire de connexion où l'utilisateur entre un nom d'utilisateur et un mot de passe, qui sont ensuite utilisés dans une requête SQL :

SELECT * FROM utilisateurs WHERE nom_utilisateur = '[USER INPUT]' AND mot_de_passe = '[USER INPUT]';

Un attaquant peut saisir un nom d'utilisateur comme admin' -- et un mot de passe aléatoire. La requête devient :

SELECT * FROM utilisateurs WHERE nom_utilisateur = 'admin' --' AND mot_de_passe = 'xyz';

Ici, -- est un commentaire en SQL, donc tout ce qui suit est ignoré, permettant à l'attaquant de se connecter en tant qu'admin sans connaître le mot de passe.

Injection pour Extraire des Données

Si un site utilise une URL comme example.com/items?id=1 pour afficher des articles, un attaquant peut modifier l'URL en example.com/items?id=1 OR 1=1 pour tenter d'extraire plus d'informations. Si la requête SQL est mal construite, cela pourrait renvoyer tous les articles de la base de données.

Comment Prévenir l'Injection SQL

Utilisation de Requêtes Préparées

Les requêtes préparées garantissent que les entrées de l'utilisateur sont traitées comme des données et non comme une partie du code SQL.

Les requêtes préparées (aussi appelées requêtes paramétrées) sont un moyen efficace de prévenir les injections SQL.
Elles permettent au SGBD de faire une distinction entre le code SQL et les données (variables), indépendamment de ce que l'utilisateur saisit.

Exemple de requête préparée en PHP avec MySQLi
// Connexion à la base de données
$conn = new mysqli('localhost', 'username', 'password', 'database');

// Requête préparée
$stmt = $conn->prepare("SELECT * FROM utilisateurs WHERE nom_utilisateur = ? AND mot_de_passe = ?");
$stmt->bind_param("ss", $username, $password);

// Assignation des valeurs et exécution
$username = $_POST['username'];
$password = $_POST['password'];
$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // Traiter les résultats
}

$stmt->close();
$conn->close();

Dans cet exemple :

Cette méthode garantit que les entrées de l'utilisateur sont traitées comme des données et non comme une partie du code SQL, empêchant ainsi l'exécution de code SQL malveillant.

Validation et Échappement des Entrées Utilisateur

Validez toutes les entrées pour s'assurer qu'elles correspondent au format attendu. Échappez les caractères spéciaux.

Utilisation de Comptes à Privilèges Limités

Exécutez des applications avec des comptes ayant le minimum de privilèges nécessaires.

Mises à Jour Régulières

Gardez votre SGBD et votre application à jour pour vous protéger contre les vulnérabilités connues.

Bonnes Pratiques de Sécurité en SQL

Gestion des Permissions et des Rôles

La création de rôles et la gestion des permissions sont des aspects essentiels de la sécurité et de l'administration des bases de données en SQL.

La création de rôles et l'attribution de permissions en MySQL aident à organiser et à sécuriser l'accès aux bases de données.
Cela permet une gestion plus flexible et centralisée des droits d'accès des utilisateurs.

Principe du Moindre Privilège

Attribuez aux utilisateurs et aux applications uniquement les privilèges nécessaires pour leurs fonctions.

Création de Rôles

Utilisez des rôles pour gérer les ensembles de permissions. Attribuez des rôles aux utilisateurs au lieu de donner des permissions directement.

Voici comment vous pouvez créer des rôles et attribuer des permissions dans un système de gestion de base de données (SGBD) comme PostgreSQL, qui offre une gestion robuste des rôles et des permissions.

Créer un Nouveau Rôle :

CREATE ROLE lecteur;

Attribuer des Permissions aux Rôles

Attribuer des Permissions de Lecture

GRANT SELECT ON ma_base_de_donnees.employes TO lecteur;

Attribuer des Permissions de Modification

GRANT INSERT, UPDATE ON ma_base_de_donnees.employes TO gestionnaire;

Activer les Rôles

Après avoir créé des rôles et attribué des permissions, vous devez activer les rôles pour les utilisateurs.

Attribuer le Rôle à un Utilisateur

GRANT lecteur TO 'jean'@'localhost';

Activer le Rôle pour la Session Actuelle

SET ROLE lecteur;

Révoquer des Permissions et Supprimer des Rôles

Révoquer des Permissions

REVOKE SELECT ON ma_base_de_donnees.employes FROM lecteur;

Supprimer un Rôle

DROP ROLE lecteur;

Audit et Surveillance

Sécurité au Niveau de l'Application

Conclusion

La sécurité en SQL est un aspect crucial de la conception et de la maintenance des systèmes de base de données.
La prévention de l'injection SQL et l'application de bonnes pratiques de sécurité aident à protéger les données contre les accès non autorisés et les manipulations malveillantes.
Une approche proactive de la sécurité, comprenant la validation des entrées, la gestion des permissions, et l'audit régulier, est essentielle pour maintenir l'intégrité et la confidentialité des données.