flawopen.com/SQL Injection en PHP/mysqli vs PDO
MySQLi vs PDO : prepared statements sûres
Une prepared statement garde le SQL fixe et transmet les valeurs séparément, comme des cases étiquetées à remplir. PDO et MySQLi le permettent. La sécurité vient du binding correct, pas du nom de la bibliothèque.
La même requête préparée avec chaque API
$userId = $_GET['id']; $sql = "SELECT id, email FROM users WHERE id = " . $userId; // Both calls execute the already-built SQL string: $rows = $mysqli->query($sql); $rows = $pdo->query($sql);
// PDO $stmt = $pdo->prepare( "SELECT id, email FROM users WHERE id = :id" ); $stmt->execute(["id" => $userId]); // MySQLi $stmt = $mysqli->prepare( "SELECT id, email FROM users WHERE id = ?" ); $stmt->bind_param("i", $userId); $stmt->execute();
La portabilité entre bases est la principale différence de PDO
PDO fournit une interface commune à plusieurs drivers ; MySQLi cible MySQL et MariaDB. PDO ne rend pas le SQL portable à lui seul : dialectes, drivers et fonctions varient.
PDO accepte des placeholders nommés comme :id ou positionnels ?, selon le driver ; ne mélangez pas les styles. MySQLi utilise ?. Les deux lient des valeurs, pas les noms de table/colonne, mots-clés ou tris.
Les drivers PDO peuvent utiliser des préparations natives ou émulées. Avec MySQL, PDO::ATTR_EMULATE_PREPARES règle l’émulation lorsqu’elle est disponible ; certains drivers l’émulent ou y reviennent si la préparation native échoue. Suivez la documentation du driver. Ce réglage ne sécurise pas le SQL interpolé : gardez le texte fixe et liez les valeurs.
Règles anti-SQL Injection pour les deux bibliothèques
Utilisez prepare() et liez chaque valeur non fiable. Gardez la syntaxe SQL fixe ; sélectionnez les identifiants dynamiques via une map stricte côté serveur ou un ensemble fini de requêtes. Une prepared statement n’autorise pas l’accès à une ligne : limitez la requête à l’utilisateur authentifié si nécessaire. Avec LIKE, le binding prévient l’injection SQL, mais % et _ restent des jokers sans échappement pour une recherche littérale.
Choisir entre PDO et MySQLi
- ✓Choisissez PDO pour une API commune entre drivers ; vérifiez le dialecte SQL et le comportement du driver lors d’une migration.
- ✓Choisissez MySQLi pour une application MySQL/MariaDB qui nécessite son API spécifique.
- ✓Dans les deux cas, recherchez interpolation, concaténation et identifiants dynamiques ; liez les valeurs et autorisez les enregistrements séparément.
Questions fréquentes
Non. Les deux peuvent lier les valeurs si la requête est préparée et les paramètres transmis. Les noms améliorent parfois la lisibilité, mais ne lient pas les identifiants et ne remplacent pas l’autorisation.
Pas systématiquement. Le support et le fallback varient selon le driver. Consultez sa documentation et les exigences de l’application. Gardez la structure SQL fixe et transmettez les valeurs comme paramètres dans tous les modes.
Non. Les paramètres représentent des valeurs, pas des identifiants ou mots-clés SQL. Associez le choix client à un ensemble fini de fragments fiables côté serveur.
Références
- Manuel PHP — prepared statements PDO
- Manuel PHP — prepared statements MySQLi
- Manuel PHP — PDO::setAttribute et préparations émulées
- FlawOpen — SQL Injection en PHP