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...

0voto

Element Punkte 3920

Wenn sie nicht wirklich fortgeschrittene Abfragen durchführen müssen, könnten Sie eine Benutzeroberfläche bereitstellen, die nur bestimmte Auswahlmöglichkeiten zulässt, wie eine Dropdown-Liste mit "Aktualisieren, Löschen, Auswählen", dann würde die nächste ddl automatisch mit einer Liste der verfügbaren Tabellen usw. gefüllt.

In Ihrem serverseitigen Code würden Sie dann diese Gruppen von Oberflächenelementen in SQL-Anweisungen umwandeln und eine parametrisierte Abfrage verwenden, um bösartige Inhalte zu stoppen

0 Stimmen

Ich habe bereits einen grafischen Query Builder implementiert, der das tut, was Sie beschreiben. Dieser kann jedoch die verschiedenen Arten von erweiterten Abfragen, die durchgeführt werden müssen, nicht ohne weiteres verarbeiten.

0 Stimmen

Das wollte ich gerade empfehlen. Aber mal ehrlich, wenn der Benutzer schlau genug ist, um erweiterte Abfragen zu erstellen, dann ist er auch schlau genug, um Ihren Server zu hacken.

0voto

BBetances Punkte 925

Das ist eine schrecklich schlechte Praxis. Ich würde eine Handvoll gespeicherter Prozeduren erstellen, um alles zu erledigen, was Sie tun wollen, sogar die fortgeschrittenen Abfragen. Präsentieren Sie sie dem Benutzer, lassen Sie ihn die gewünschte Prozedur auswählen und übergeben Sie Ihre Parameter.

Die Antwort über meiner ist auch sehr gut.

0 Stimmen

Zu Ihrer Information: Die Reihenfolge der Antworten ändert sich je nach Abstimmung. Der Verweis auf "die Antwort über meiner" ist also auf lange Sicht nicht sinnvoll. Wenn Ihnen eine Antwort gefällt, bewerten Sie sie hoch und/oder fügen Sie ihr einen Kommentar hinzu.

0 Stimmen

Danke, Bruder, das war mir nie klar.

0 Stimmen

Könnten Sie einen Link zu der genannten Antwort angeben?

0voto

Saif Khan Punkte 17922

Obwohl ich mit Joel Coehoorn und SQLMenace übereinstimme, haben einige von uns "Anforderungen". Anstatt sie Ad-hoc-Abfragen senden zu lassen, sollten Sie einen visuellen Query Builder erstellen, wie er in den MS-Beispielanwendungen auf asp.net zu finden ist, oder dies versuchen リンク .

Ich habe nichts gegen die von Joel vorgebrachten Argumente. Er hat Recht. Wenn Benutzer (wir sprechen hier von Benutzern, denen es egal ist, was Sie durchsetzen wollen) Abfragen stellen, ist das wie eine Anwendung ohne "Business Logic Layer", ganz zu schweigen von den zusätzlichen Fragen, die zu beantworten sind, wenn bestimmte Ergebnisse nicht mit anderen unterstützenden Anwendungsergebnissen übereinstimmen.

0 Stimmen

Es gibt bereits einen visuellen Query Builder. Dies ist eine Ergänzung für fortgeschrittene Abfragen, die nicht visuell bearbeitet werden können.

0 Stimmen

Dann, wie Joel sagte, versuchen Sie Replikation (ich würde Snapshot bevorzugen), stellen Sie sicher, dass Ihre Zugriffsrechte vorhanden sind und setzen Sie einfach einen Standard-SQL-Editor, ver basic, anstatt das Rad neu zu erfinden.

0voto

SQLMenace Punkte 128184

Hier ein weiteres Beispiel

der Hacker braucht den echten Tabellennamen nicht zu kennen, er/sie kann undokumentierte Procs wie diese ausführen

sp_msforeachtable 'print ''?''' 

nur statt drucken wird es fallen gelassen

0 Stimmen

Aber wenn der DB-Benutzer nur Select und Update-Rechte hat, als Sie nicht in der Lage, gespeicherte Prozeduren wie diese ausführen, richtig?

0 Stimmen

Dieser proc kann von jedem ausgeführt werden, der diesen EXEC master ausführt..sp_helprotect 'sp_msforeachtable' output Owner Object Grantee Grantor ProtectType Action Column dbo sp_MSforeachtable public dbo Grant Execute .

0voto

Jaloopa Punkte 722

Viele Antworten besagen, dass dies keine gute Idee ist, aber manchmal ist es das, worauf die Anforderungen bestehen. Es gibt jedoch ein Problem, das ich in den "Wenn Sie es trotzdem tun müssen"-Vorschlägen noch nicht entdeckt habe: Stellen Sie sicher, dass alle Aktualisierungsanweisungen eine WHERE-Klausel enthalten. Es ist nur allzu leicht, die

UPDATE ImportantTable
SET VitalColumn = NULL

und verpassen das Wichtige

WHERE UserID = @USER_NAME

Wenn eine Aktualisierung für die gesamte Tabelle erforderlich ist, ist es einfach genug, Folgendes hinzuzufügen

WHERE 1 = 1

Das Erfordernis der Where-Klausel hält einen böswilligen Benutzer nicht davon ab, schlechte Dinge zu tun, aber es sollte versehentliche Änderungen der gesamten Tabelle reduzieren.

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