5 Stimmen

Wie verhindert man Sql-Injection bei benutzergenerierten Sql-Abfragen?

Ich habe ein Projekt (privat, ASP.net-Website, passwortgeschützt mit https), wo eine der Anforderungen ist, dass der Benutzer in der Lage sein, Sql-Abfragen, die direkt die Datenbank abfragen wird eingeben. Ich muss in der Lage sein, diese Abfragen zuzulassen und gleichzeitig zu verhindern, dass sie die Datenbank selbst beschädigen und auf Daten zugreifen oder diese aktualisieren, auf die sie nicht zugreifen/aktualisieren können sollten.

Für die Umsetzung habe ich mir folgende Regeln ausgedacht:

  1. Verwenden Sie einen db-Benutzer, der sólo hat die Berechtigung für Select Table/View und Update Table (alle anderen Befehle wie drop/alter/truncate/insert/delete werden also nicht ausgeführt).
  2. Überprüfen Sie, ob die Anweisung mit den Worten "Select" oder "Update" beginnt.
  3. Überprüfen Sie (mit Hilfe von Regex), dass in der Anweisung keine Semikolons vorkommen, die nicht von einfachen Anführungszeichen, Leerzeichen und Buchstaben umgeben sind. (Der Gedanke dabei ist, dass die einzige Möglichkeit, eine zweite Abfrage einzufügen, darin besteht, die erste mit einem Semikolon zu beenden, das nicht Teil einer Eingabezeichenfolge ist).
  4. Überprüfen Sie (mit Hilfe von Regex), ob der Benutzer die Berechtigung hat, auf die Tabellen zuzugreifen, die abgefragt/aktualisiert, in Joins einbezogen werden, usw. Dies schließt alle Unterabfragen ein. (Dies wird u. a. dadurch erreicht, dass der Benutzer eine Reihe von Tabellennamen verwendet, die in der Datenbank nicht existieren; ein Teil des Abfrageparsings besteht darin, die korrekten entsprechenden Tabellennamen in der Abfrage zu ersetzen).

Habe ich etwas übersehen?

Das Ziel ist, dass die Benutzer in der Lage sein, Abfragen/Aktualisierungen von Tabellen, auf die sie Zugriff haben, auf jede beliebige Art und Weise, die sie für richtig halten, durchzuführen und alle versehentlichen oder böswilligen Versuche, die Datenbank zu beschädigen, zu verhindern.

0 Stimmen

Dies ist keine SQL-Injektion, wenn die Benutzer tatsächlich SQL schreiben. Es scheint, dass der Satz das, was Sie gemeint haben, richtig wiedergegeben hat!

0 Stimmen

Daran habe ich auch schon gedacht, aber ich konnte mich nicht entscheiden, wie ich es besser ausdrücken sollte. Vielleicht "Hot to prevent mischievous activity on user generated sql queries"? Ich bin offen dafür, den Titel in etwas zu ändern, das mehr Sinn ergibt...

16voto

Joel Coehoorn Punkte 377088

Dies ist eine schlechte Idee, und zwar nicht nur aus der Sicht der Injektionsprävention. Es ist sehr einfach für einen Benutzer, der es nicht besser weiß, versehentlich eine Abfrage auszuführen, die alle Ihre Datenbankressourcen (Arbeitsspeicher und CPU) in Anspruch nimmt, was effektiv zu einem Denial-of-Service-Angriff führt.

Wenn Sie muss Um dies zu ermöglichen, ist es am besten, einen völlig separaten Server für diese Abfragen zu betreiben und ihn mit Hilfe der Replikation so nah wie möglich an einer exakten Spiegelung des Produktionssystems zu halten. Das funktioniert natürlich nicht mit Ihrer UPDATE-Anforderung.

Aber ich möchte noch einmal sagen: Das funktioniert einfach nicht. Sie können Ihre Datenbank nicht schützen, wenn die Benutzer Ad-hoc-Abfragen durchführen können.

0 Stimmen

Ich bin damit einverstanden. Der einzige Gedanke, den ich mir vorstellen kann, ist, nur Selects auf einigen wenigen Tabellen zuzulassen und sonst nichts. Sogar Aktualisierungen können der Datenbank schrecklich schaden. Und wie Sie erwähnt haben, können "schlechte" Selects auch Ihre Datenbank zerstören.

0 Stimmen

Ich habe es immer für eine schlechte Idee gehalten, überhaupt Nutzer zu haben! Hängt es nicht davon ab, wer die Nutzer sind, ob dies eine schlechte Idee ist?

0 Stimmen

Nein. Selbst erfahrene Benutzer machen hin und wieder einen Fehler. Sie wollen nicht, dass Ihre Mitarbeiter Ad-hoc-Abfragen mit Produktionsdaten durchführen.

4voto

SQLMenace Punkte 128184

Was ist mit diesem Zeug, stellen Sie sich einfach vor, der Select ist ein EXEC

select convert(varchar(50),0x64726F70207461626C652061)

0 Stimmen

Wie funktioniert das genau und wie kann ich eine Abfrage in eine solche umwandeln? Außerdem muss ich in der Lage sein, auch Aktualisierungsabfragen zu verarbeiten.

0 Stimmen

@Yaakov: Führen Sie es in einem Abfragefenster aus und sehen Sie, was das Ergebnis der Konvertierung ist.

0 Stimmen

Für diejenigen, die keinen SQL-Server zur Hand haben, lässt sich der obige Befehl in "drop table a" umwandeln. Im Grunde ist dies eine Lektion, dass man eine Freitextabfrage einfach nicht "sicher" machen kann, indem man nur nach bestimmten Zeichen oder Mustern sucht.

4voto

Dave Costa Punkte 45801

Mein Gefühl sagt mir, dass Sie sich darauf konzentrieren sollten, die Kontoberechtigungen und Berechtigungen so eng wie möglich zu setzen. Schauen Sie sich die Sicherheitsdokumentation Ihres RDBMS gründlich an. Es kann durchaus sein, dass es Funktionen gibt, mit denen Sie nicht vertraut sind und die sich als hilfreich erweisen würden (ich glaube, dass z. B. Oracles Virtual Private Database in dieser Art von Szenario nützlich sein kann).

Insbesondere Ihre Idee "Überprüfen Sie (mit Regex), dass der Benutzer die Berechtigung hat, auf die Tabellen zuzugreifen, die abgefragt/aktualisiert werden, die in Joins enthalten sind usw." klingt, als würden Sie versuchen, die bereits in die Datenbank integrierte Sicherheitsfunktionalität neu zu implementieren.

3voto

Lasse V. Karlsen Punkte 364542

Was Ihnen entgeht, ist der Einfallsreichtum eines Angreifers, der Lücken in Ihrer Anwendung findet.

Ich kann Ihnen praktisch garantieren, dass Sie nicht in der Lage sein werden, alle Löcher zu schließen, wenn Sie dies zulassen. Es könnte sogar Fehler in der Datenbank-Engine geben, von denen Sie nichts wissen, die aber dazu führen, dass eine SQL-Anweisung, die Sie für sicher halten, in Ihrem System Schaden anrichtet.

Kurz gesagt: Das ist eine denkbar schlechte Idee!

3voto

BradC Punkte 38356

Nun, Sie haben schon genug Leute, die Ihnen sagen, dass Sie nicht in der Lage sind. "Tu das nicht" Wenn sie Sie also nicht davon abbringen können, haben wir hier ein paar Ideen:

Das Gute einbeziehen, nicht versuchen, das Schlechte auszuschließen
(Ich glaube, die richtige Terminologie lautet Whitelisting gegen Schwarze Liste ) Damit meine ich suchen Sie nicht nach bösen oder ungültigen Dingen, die Sie wegwerfen können (es gibt zu viele Möglichkeiten, es zu schreiben oder zu verschleiern), suchen Sie stattdessen nach gültige Angaben zu machen und werfen Sie alles andere weg.

Sie haben bereits in einem anderen Kommentar erwähnt, dass Sie nach einer Liste von benutzerfreundlichen Tabellennamen suchen und die tatsächlichen Schema-Tabellennamen ersetzen wollen. Genau das meine ich - wenn Sie das tun, dann tun Sie es auch mit Feldnamen.

Ich tendiere aber immer noch zu einer Art grafischer Benutzeroberfläche: Wählen Sie hier die Tabellen aus, die Sie anzeigen möchten, wählen Sie hier die Felder aus, die Sie sehen möchten, verwenden Sie einige Dropdowns, um eine Where-Klausel zu erstellen usw. Das ist mühsam, aber wahrscheinlich einfacher.

0 Stimmen

Ich habe diese Benutzeroberfläche bereits erstellt, und es war eine Qual. Aber es kann einfach nicht mit komplexen Abfragen, Unterabfragen, etc.

0 Stimmen

Und die Feldnamen regeln sich quasi von selbst - es gibt keine Beschränkung für Felder, die sie innerhalb einer einzelnen Tabelle sehen können (solange sie diese Tabelle sehen können). Aktualisierungsabfragen sind jedoch ein anderes Thema (siehe tinyurl.com/8edl3d )

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X