2016-11-05 3 views
0

Um SQL Injection zu vermeiden, habe ich einige recherchierte und basierte auf this Antwort Ich fing an, MySQLi vorbereitete Statemets verwenden. Alles lief gut, bis ich in die order by und order type Parameter kam, die vom Frontend basierend auf dem, was der Benutzer klickt, gesendet werden. Um genauer zu sein habe ich einige Tabellen mit einigen Überschriften und Benutzer kann die Daten bezüglich des Namens, des Preises, des Datums usw. arrangieren und auch er kann zwischen ASC oder DESC wählen. Ich speichere dies in einem Eingabetyp versteckt, also denke ich, dass sie das unter Verwendung von firebug ändern können. Aus diesem Grund muss ich sicher sein, dass sie nichts in meine Datenbank injizieren können.PHP | MySQLi vorbereitete Anweisungen - Handhabung von Bestell- und Auftragsartparametern

$stmt = $dbConnection->prepare('SELECT * FROM mytable WHERE 1 ORDER BY ? ?'); 
$stmt->bind_param('ss', $_GET['order_by'], $_GET['order_type']); 

Es scheint, dass ich einen Fehler erhalte. Ich habe einige Nachforschungen gemacht und jemand hat gesagt, dass es keine Lösung dafür gibt, eine andere Person sagte, dass die einzige Lösung fest codiert sei und eine andere Person sagte, dass ich aufhören muss vorbereitete Anweisungen zu verwenden und mysql_real_escape_string auszuprobieren, aber in der Antwort, die ich verlinkte, sagte jemand:

Wenn Sie eine aktuelle Version von PHP verwenden, die mysql_real_escape_string Option unten nicht mehr erläutert werden

verfügbar sein Also ich gueess dies auch nicht der richtige Weg ist. Also meine Frage bleibt, was soll ich als nächstes tun? Gibt es eine Lösung für dieses Problem?

+0

Sie können Parameter nur für Werte verwenden. Sie können sie nicht als Ersatz für Tabellen- und Spaltennamen verwenden. – Barmar

+0

Der Grund, dass mysql_real_escape_string nicht verfügbar ist, liegt daran, dass die mysql-Erweiterung nicht mehr vorhanden ist. Aber wenn Sie 'mysqli' verwenden, hat es' mysqli_real_escape_string'. Aber das ist nicht nützlich, weil es Strings entzieht, nicht Spaltennamen. – Barmar

Antwort

1

SQL erlaubt keine Parameter für Spaltenaliase, Ausdrücke oder Schlüsselwörter. Sie müssen sie in die Abfrage direkt stopfen:

$stmt = $dbConnection->prepare('SELECT * FROM mytable WHERE 1 ORDER BY '.$_GET['order_by'].' '.$_GET['order_type'); 

Wenn diese von einem Benutzer zur Verfügung gestellt werden, sollten Sie sie überprüfen, bevor sie in den Query-String setzen.

+0

Wenn ich sie vorher selbst validieren muss, warum sollte ich dann vorbereitete Statemets verwenden? ..sie behandeln das nicht an meiner Stelle? – paulalexandru

+1

@paulalexandru Verwenden Sie eine vorbereitete Anweisung, wenn die Abfrage andere Parameter aufweist. – Barmar

+0

@Barmar - Warum andere Parameter? Warum nicht alle Parameter? Diese Parameter kamen von der Benutzerseite, er kann sie bearbeiten, wenn er will. – paulalexandru

2

Sie können Parameter für Spaltennamen nicht nur für Werte verwenden. Überprüfen Sie, ob die Spaltennamen gültig sind.

$allowed_order_by = array('col1', 'col2', 'col3', ...); 
$allowed_order_type = array('asc', 'desc', ''); 
if (in_array(strtolower($_GET['order_by']), $allowed_order_by) && 
    in_array(strtolower($_GET['order_type'], $allowed_order_type)) { 
    $stmt = $dbConnection->prepare(" 
     SELECT * FROM mytable 
     ORDER BY {$_GET['order_by']} {$_GET['order_type']}"); 
    $stmt->execute(); 
} 
+0

'$ _GET ['order_ty [e]' wirft Syntax-Highlighting ab. Sie haben vielleicht '$ _GET ['order_type']' ' –

+0

@ Fred-ii- Fühlen Sie sich frei, offensichtliche Tippfehler wie diese zu bearbeiten – Barmar

+0

Ich hätte aber TBH, war nicht ganz sicher von dem, was ein anderes Array hätte sein können. –

Verwandte Themen