Frage

Ich habe einige Codes, die gegen Injektion parametrisierte Abfragen verhindern verwendet, aber ich muß auch in der Lage sein, dynamisch die Abfrage zu erstellen, unabhängig von der Struktur der Tabelle. Was ist der richtige Weg, dies zu tun?

Hier ist ein Beispiel ist, sage ich eine Tabelle mit Spalten Namen haben, Adresse, Telefon. Ich habe eine Web-Seite, wo ich laufe Spalten anzeigen und wählen Sie im Dropdown-mit ihnen als Optionen füllen.

Als nächstes habe ich eine Textbox namens Suche . Diese Textbox wird als Parameter verwendet wird.

Zur Zeit meines Code sieht etwa so aus:

result = pquery('SELECT * FROM contacts WHERE `' + escape(column) + '`=?', search);

Ich erhalte ein ekliges Gefühl von ihm aber. Der Grund, warum ich parametrisierte Abfragen bin mit ist zu vermeiden, mit entkommen . Auch entkommen ist wahrscheinlich nicht für die entweichenden Spaltennamen.

Wie kann ich sicherstellen, dass dies so funktioniert, ich beabsichtige?

Bearbeiten: Der Grund, warum ich dynamische Abfragen verlangen, ist, dass das Schema vom Benutzer konfigurierbar ist, und ich werde nicht um etwas hart codiert zu beheben sein.

War es hilfreich?

Lösung

Statt die Spaltennamen von vorbei, nur eine Kennung übergeben, die Sie Code zu einem Spaltennamen übersetzen wird eine hartkodierte Tabelle. Dies bedeutet, dass Sie keine schädlichen Daten über das Sein weitergegeben kümmern müssen, da alle Daten entweder rechtlich übersetzt werden, oder sind bekannt für ungültig. Psudoish Code:

@columns = qw/Name Address Telephone/;
if ($columns[$param]) {
  $query = "select * from contacts where $columns[$param] = ?";
} else {
  die "Invalid column!";
}

run_sql($query, $search);

Andere Tipps

Der Trick ist, in Ihrem Entkommen und Validierung von Routinen, zuversichtlich zu sein. Ich benutze meine eigene SQL-Escape-Funktion, die für Literale verschiedenen Typen überlastet ist. Nirgends ich Ausdrücke einfügen (im Gegensatz zu zitierte Literalwerte gegen) direkt von Benutzereingaben.

Dennoch kann es geschehen, empfehle ich eine separate - und streng - Funktion zur Validierung des Spaltennamen. Lassen Sie es nur eine einzige Kennung, so etwas wie

akzeptieren
/^\w[\w\d_]*$/

Sie müssen werden auf Annahmen stützen Sie Ihre eigenen Spaltennamen machen.

Ich verwende ADO.NET und die Verwendung von SQL-Befehle und SqlParameters auf diese Befehle, die sich um die Escape-Problem nehmen. Wenn Sie also auch in einem Microsoft-Tool-Umgebung sind, kann ich sagen, dass ich diese verwenden sehr sucesfully dynamische SQL zu bauen und noch meine Parameter schützen

viel Glück

Machen Sie die Spalte basierend auf den Ergebnissen einer anderen Abfrage auf eine Tabelle, die die möglichen Schema Werte auflistet. In dieser zweiten Abfrage können Sie die wählen, um die Spaltennamen codieren, die verwendet wird, um das Schema zu definieren. wenn keine Zeilen zurückgegeben werden dann die eingegebene Spalte ist ungültig.

Im Standard-SQL, anbei erhalten Sie begrenzte Bezeichner in doppelten Anführungszeichen. Dies bedeutet, dass:

SELECT * FROM "SomeTable" WHERE "SomeColumn" = ?

aus einer Tabelle auswählen, wird mit der gezeigten Sometable Kapitalisierung (keinen Fall umgesetzten Version des Namen) genannt, und wird eine Bedingung an eine Spalte namens SomeColumn mit der gezeigten Kapitalisierung gelten.

Von selbst, das ist nicht sehr hilfreich, aber ... wenn Sie die Flucht anwenden können () Technik mit doppelten Anführungszeichen, um die Namen über Ihre Web-Formular eingegeben, dann können Sie Ihre Abfrage maßen sicher aufzubauen.

Natürlich, Sie sagten, Sie entkommen mit vermeiden wollte - und in der Tat Sie müssen es nicht auf die Parameter verwenden, wenn Sie das schaffen? Platzhalter. Aber wo Sie setzen vom Benutzer bereitgestellte Daten in die Abfrage, müssen Sie sich vor böswilligen Menschen schützen.

Verschiedene DBMS haben verschiedene Möglichkeiten, begrenzten Bezeichner bereitstellt. MS SQL Server, zum Beispiel, scheinen eckige Klammern zu verwenden [Sometable] anstelle von doppelten Anführungszeichen.

Spaltennamen in einigen Datenbanken können Leerzeichen enthalten, mit dem Sie die Spaltennamen zitieren müssen bedeuten würden, aber wenn Ihre Datenbank keine solche Spalten enthält, nur die Spaltennamen durch einen regulären Ausdruck oder irgendeine Art von Kontrolle vor dem Spleißen läuft in die SQL:

if ( $column !~ /^\w+$/ ) {
  die "Bad column name [$column]";
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top