Maison >base de données >tutoriel mysql >Les instructions préparées peuvent-elles gérer les noms de tables paramétrés pour empêcher l'injection SQL ?

Les instructions préparées peuvent-elles gérer les noms de tables paramétrés pour empêcher l'injection SQL ?

DDD
DDDoriginal
2025-01-23 17:56:09846parcourir

Can Prepared Statements Handle Parameterized Table Names to Prevent SQL Injection?

Relevés préparés : peuvent-ils gérer les noms de tables paramétrés ?

Cet article aborde la question cruciale de savoir si les instructions préparées peuvent gérer efficacement les noms de tables paramétrés pour empêcher les vulnérabilités d'injection SQL.

Le problème :

L'intégration directe des données fournies par l'utilisateur dans les requêtes SQL, y compris les noms de tables, constitue un risque de sécurité majeur. Prenons cet exemple :

<code class="language-php">function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol )
{
    $statement = $mysqli->prepare("INSERT INTO " .$new_table . " VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'sssisss', $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}</code>

La concaténation .$new_table. rend cette fonction vulnérable à l'injection SQL si $new_table n'est pas correctement nettoyée.

Tentative de paramétrage :

Une tentative courante pour atténuer ce problème consiste à essayer de paramétrer le nom de la table :

<code class="language-php">function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol )
{
    $statement = $mysqli->prepare("INSERT INTO (?) VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'ssssisss', $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}</code>

La réalité :

Malheureusement, cette approche échoue. Les instructions préparées sont conçues pour protéger contre l'injection de valeur runtime, et non contre la modification de la structure de la requête SQL elle-même. L'analyseur de base de données interprète le nom de la table comme faisant partie de la structure de la requête, et non comme un paramètre d'exécution. Le remplacer par un espace réservé entraîne un SQL invalide.

Même avec des systèmes offrant l'émulation d'instructions préparées, comme PDO, le résultat serait une requête invalide (par exemple, SELECT * FROM 'mytable' au lieu de SELECT * FROM mytable).

La solution :

Le seul moyen fiable d'empêcher l'injection SQL lors du traitement des noms de table fournis par l'utilisateur est d'utiliser une liste blanche stricte. Cela implique de prédéfinir une liste de noms de table autorisés et de garantir que tout nom de table fourni par l'utilisateur est vérifié par rapport à cette liste blanche avant d'être utilisé dans une requête. N'utilisez jamais directement les entrées de l'utilisateur pour construire des requêtes SQL impliquant des noms de tables.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn