Les injections SQL (SQL Injection ou SQLi) figurent parmi les attaques les plus courantes et dangereuses du web. Exploitées par des cybercriminels, elles permettent d’interagir directement avec la base de données d’un site mal sécurisé, souvent pour voler, modifier ou supprimer des données sensibles.
Même si Symfony intègre des mécanismes pour limiter ce type de faille, il est essentiel de bien comprendre comment les prévenir efficacement. Voici un guide complet pour sécuriser ton site Symfony contre les injections SQL.
Comprendre l’injection SQL
Une injection SQL se produit lorsque des données entrées par l’utilisateur (formulaire, URL, paramètre GET/POST...) sont insérées dans une requête SQL sans être correctement filtrées ou échappées. Exemple classique :
php
// Risque d'injection SQL $email = $_GET['email']; $query = "SELECT * FROM users WHERE email = '$email'";
Un attaquant pourrait injecter une requête malveillante comme :
sql
' OR 1=1 --
Résultat : la requête renvoie tous les utilisateurs, exposant ainsi les données de la base.
Bonnes pratiques à appliquer avec Symfony
Symfony, avec Doctrine (ORM par défaut), fournit plusieurs protections contre les injections SQL. Voici les techniques recommandées :
1. Utiliser Doctrine avec des paramètres liés
Doctrine prépare les requêtes avec des valeurs liées (bound parameters) automatiquement :
php
$user = $entityManager->getRepository(User::class)->findOneBy(['email' => $email]);
Ici, pas de risque : Doctrine utilise une requête préparée, ce qui empêche l'injection.
2. Éviter le SQL brut (native queries)
Même si Symfony permet d’exécuter des requêtes SQL brutes, il faut éviter de concaténer des données utilisateur directement dans la requête :
À éviter :
php
$conn->executeQuery("SELECT * FROM user WHERE email = '$email'");
À préférer :
php
$conn->executeQuery( 'SELECT * FROM user WHERE email = :email', ['email' => $email] );
3. Valider et filtrer les données utilisateur
Utilise les contraintes de validation Symfony (Assert\NotBlank
, Assert\Email
, Assert\Type
, etc.) pour valider les champs avant qu’ils ne soient utilisés dans une requête.
php
use Symfony\Component\Validator\Constraints as Assert; class Contact { /** * @Assert\Email() * @Assert\NotBlank() */ public $email; }
4. Ne jamais faire confiance aux entrées utilisateur
Même si les données viennent d’un formulaire bien conçu, il est important d’assumer qu’elles peuvent être modifiées côté client. Applique toujours une validation côté serveur.
5. Activer le mode "dev" pour traquer les erreurs
Pendant le développement, Symfony affiche des erreurs SQL détaillées. En production, ce mode doit être désactivé (APP_ENV=prod
) pour éviter de révéler trop d'informations sur la structure des requêtes en cas de faille.
Bonus : utiliser un WAF et des outils d’analyse
Pour renforcer la sécurité :
-
Utilise un pare-feu applicatif (WAF) comme ModSecurity.
-
Mets en place une surveillance des logs SQL.
-
Utilise des outils comme Symfony Security Checker ou OWASP ZAP pour détecter les failles potentielles.
Et les formulaires Symfony ?
Les formulaires Symfony génèrent automatiquement du code sécurisé et valident les champs grâce aux contraintes. Évite de récupérer des valeurs en dehors du composant Form
si vous ne maîtrisez pas leur validation.
En résumé
Pour sécuriser ton site Symfony contre les injections SQL :
Mesure | Protection apportée |
---|---|
Doctrine findOneBy() -> |
Requêtes préparées automatiquement |
Requêtes DQL/QueryBuilder -> | Liage sécurisé des paramètres |
Validation des données -> | Évite les valeurs malveillantes |
Pas de concaténation SQL -> | Supprime les injections directes |
Logs et audits -> | Détection d’anomalies |
Symfony est un framework robuste qui intègre de nombreuses protections, mais la sécurité dépend aussi des bonnes pratiques du développeur. Adopte une approche défensive dès la conception de votre code !