Heim >Datenbank >MySQL-Tutorial >Können vorbereitete Anweisungen parametrisierte Tabellennamen verarbeiten, um SQL-Injection zu verhindern?
Vorbereitete Anweisungen: Können sie mit parametrisierten Tabellennamen umgehen?
Dieser Artikel befasst sich mit der entscheidenden Frage, ob vorbereitete Anweisungen effektiv mit parametrisierten Tabellennamen umgehen können, um SQL-Injection-Schwachstellen zu verhindern.
Das Problem:
Das direkte Einbetten von vom Benutzer bereitgestellten Daten, einschließlich Tabellennamen, in SQL-Abfragen stellt ein großes Sicherheitsrisiko dar. Betrachten Sie dieses Beispiel:
<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>
Die Verkettung .$new_table.
macht diese Funktion anfällig für SQL-Injection, wenn $new_table
nicht ordnungsgemäß bereinigt wird.
Parametrisierungsversuch:
Ein häufiger Versuch, dies zu mildern, besteht darin, den Tabellennamen zu parametrisieren:
<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>
Die Realität:
Leider scheitert dieser Ansatz. Vorbereitete Anweisungen sollen vor der Laufzeit-Wertinjektion schützen und nicht vor der Änderung der Struktur der SQL-Abfrage selbst. Der Datenbankparser interpretiert den Tabellennamen als Teil der Struktur der Abfrage und nicht als Laufzeitparameter. Das Ersetzen durch einen Platzhalter führt zu ungültigem SQL.
Selbst bei Systemen, die eine vorbereitete Anweisungsemulation anbieten, wie PDO, wäre das Ergebnis eine ungültige Abfrage (z. B. SELECT * FROM 'mytable'
anstelle von SELECT * FROM mytable
).
Die Lösung:
Die einzige zuverlässige Möglichkeit, SQL-Injection beim Umgang mit vom Benutzer bereitgestellten Tabellennamen zu verhindern, ist die Verwendung einer strikten Whitelist. Dazu gehört die Vordefinition einer Liste zulässiger Tabellennamen und die Sicherstellung, dass alle vom Benutzer bereitgestellten Tabellennamen mit dieser Whitelist verglichen werden, bevor sie in einer Abfrage verwendet werden. Verwenden Sie niemals direkt Benutzereingaben, um SQL-Abfragen mit Tabellennamen zu erstellen.
Das obige ist der detaillierte Inhalt vonKönnen vorbereitete Anweisungen parametrisierte Tabellennamen verarbeiten, um SQL-Injection zu verhindern?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!