Kann ich den Tabellennamen in einer vorbereiteten Anweisung parametrisieren?

Lesezeit: 3 Minuten

Kann ich den Tabellennamen in einer vorbereiteten Anweisung parametrisieren
GK1667

Ich habe die Funktion mysqli_stmt_bind_param mehrmals verwendet. Wenn ich jedoch Variablen trenne, die ich vor SQL-Injection schützen möchte, treten Fehler auf.

Hier ist ein Codebeispiel:

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();
}

Kann man die irgendwie ersetzen .$new_table. mit einer anderen Fragezeichenanweisung verketten, eine weitere Bindungsparameteranweisung erstellen oder die vorhandene zum Schutz vor SQL-Injection hinzufügen?

So oder in irgendeiner Form:

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();
}

  • Nein, eine parametrisierte Abfrage fügt die Parameterwerte nicht einfach in die Abfragezeichenfolge ein, sondern versorgt das RDBMS mit der parametrisierten Abfrage und den Parametern separat. Aber eine solche Abfrage kann keinen Tabellennamen oder Feldnamen als Parameter haben. Die einzige Möglichkeit, dies zu tun, besteht darin, den Tabellennamen dynamisch in die Abfragezeichenfolge zu codieren, so wie Sie es bereits getan haben. Wenn diese Zeichenfolge potenziell angreifbar ist, sollten Sie sie zuerst validieren. B. gegen eine White-List-Liste zulässiger Tabellen.

    – MatBailie

    3. Juli 2012 um 14:23 Uhr


  • Die Verwendung der mysqli-Erweiterung ist sicher, machen Sie weiter! Aber vergessen Sie nicht, alle Ihre Strings zu bereinigen und zu validieren.. ob Tabellen- oder Feldname oder was auch immer gegen Ihre Datenbank steht!

    – devasia2112

    3. Juli 2012 um 14:24 Uhr


  • Gibt es eine bestimmte Funktion, die Sie gerne zum Desinfizieren verwenden?

    – GK1667

    3. Juli 2012 um 14:33 Uhr

  • @ user1475765 Die Verwendung von Escape-Funktionen für Ihren Tabellennamen schützt Sie vor nichts, verwenden Sie eine Whitelist.

    – jeroen

    3. Juli 2012 um 15:49 Uhr

  • mögliches Duplikat von Können PHP-PDO-Anweisungen den Tabellennamen als Parameter akzeptieren?

    – aussen

    3. Juli 2012 um 18:14 Uhr

Kann ich den Tabellennamen in einer vorbereiteten Anweisung parametrisieren
Sam Graham

Kurze Antwort auf Ihre Frage ist “nein”.

Genau genommen erlauben vorbereitete Anweisungen auf Datenbankebene nur das Binden von Parametern für “Werte”-Bits der SQL-Anweisung.

Eine Denkweise dafür ist “Dinge, die bei der Ausführung der Anweisung zur Laufzeit ersetzt werden können, ohne ihre Bedeutung zu ändern”. Die Tabellennamen gehören nicht zu diesen Laufzeitwerten, da sie die Gültigkeit der SQL-Anweisung selbst bestimmen (dh welche Spaltennamen gültig sind) und eine Änderung zur Ausführungszeit möglicherweise ändern würde, ob die SQL-Anweisung gültig war.

Auf einer etwas höheren Ebene, sogar in Datenbankschnittstellen, die die Parameterersetzung vorbereiteter Anweisungen emulieren, anstatt vorbereitete Anweisungen tatsächlich an die Datenbank zu senden, wie z die Datenbank in diesen Systemen), wäre der Wert des Tabellenplatzhalters eine Zeichenfolge und als solche in das an die Datenbank gesendete SQL eingeschlossen, so SELECT * FROM ? mit mytable da der Param tatsächlich am Ende senden würde SELECT * FROM 'mytable' an die Datenbank, die ungültiges SQL ist.

Am besten machst du einfach weiter

SELECT * FROM {$mytable}

aber du absolut sollte eine weiße Liste von Tabellen haben, die Sie zuerst überprüfen, wenn das so ist $mytable kommt von Benutzereingaben.

  • Toller Rat, aber meiner Erfahrung nach kann dies nicht auf größere dynamische Websites zutreffen. Wenn Ihre Website über eine Einrichtung für mehrere Benutzer, einen großen und ständig aktualisierten Bestand usw. verfügt, ist diese Lösung äußerst schwierig anzuwenden.

    – Igal Zeifman

    4. Juli 2012 um 11:31 Uhr

  • Die Größe der Website hat sehr wenig mit der Anzahl der Tabellen zu tun und zu wissen, an welche Endbenutzer Abfragen über Parameter richten können. Letztendlich ist es eine seltsame Website, die Endbenutzer dies überhaupt erst tun lässt.

    – Sam Graham

    5. Juli 2012 um 9:57 Uhr


Die gleiche Regel gilt beim Versuch, eine “Datenbank” zu erstellen.

Sie können eine vorbereitete Anweisung nicht verwenden, um eine Datenbank zu binden.

Dh:

CREATE DATABASE IF NOT EXISTS ?

wird nicht funktionieren. Verwenden Sie stattdessen eine Safelist.

992920cookie-checkKann ich den Tabellennamen in einer vorbereiteten Anweisung parametrisieren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy