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

2voto

Daniel Punkte 1496

Wie bereits von anderen erwähnt, ist es keine gute Idee, dies den Endnutzern zu überlassen. Ich vermute, dass die Anforderung nicht wirklich darin besteht, dass der Benutzer Ad-hoc-SQL benötigt, sondern eher darin, dass er Daten auf eine Weise abrufen und aktualisieren kann, die ursprünglich nicht vorgesehen war. Um Abfragen zu ermöglichen, sollten Sie, wie Joel vorschlägt, eine "schreibgeschützte" Datenbank behalten, aber eine Berichtsanwendung wie Microsoft Reporting Services oder Data Dynamics Active Reports verwenden, damit die Benutzer Ad-hoc-Berichte erstellen und ausführen können. Beide bieten meiner Meinung nach Möglichkeiten, den Benutzern eine gefilterte Sicht auf "ihre" Daten zu präsentieren.

Bei den Aktualisierungen ist es etwas schwieriger - ich kenne keine Tools, die dies ermöglichen. Eine Option könnte sein, Ihre Anwendung so zu gestalten, dass Entwickler schnell Plugins schreiben können, um neue Formulare für die Aktualisierung von Daten bereitzustellen. Das Plugin müsste ein UI-Formular, Code zur Überprüfung, ob der aktuelle Benutzer es ausführen kann, und Code zur Ausführung bereitstellen. Ihre Anwendung würde alle Plugins laden und die Formulare bereitstellen, auf die ein Benutzer Zugriff hat.

2voto

Rinat Abdullin Punkte 22138

Selbst scheinbar sichere Technologien wie Dynamischer LINQ, ist nicht sicher vor Code-Injection-Problemen und Sie sprechen davon, Zugang auf niedriger Ebene zu gewähren.

Egal wie stark Sie Abfragen bereinigen und Berechtigungen einstellen, es ist wahrscheinlich immer noch möglich, Ihre DB durch das Senden einer CPU-intensiven Abfrage einzufrieren.

Eine der "Schutzoptionen" besteht also darin, eine Meldung einzublenden, die besagt, dass alle Abfragen, die auf eingeschränkte Objekte zugreifen oder unerwünschte Nebeneffekte verursachen, werden auf dem Benutzerkonto protokolliert und sofort an die Administratoren gemeldet .

Eine andere Möglichkeit ist, nach einer besseren Alternative zu suchen (d.h. wenn Sie wirklich Daten verarbeiten und aktualisieren müssen, warum sollten Sie nicht eine API bereitstellen, um dies sicher zu tun).

1voto

Paulo Lopes Punkte 5432

Eine (vielleicht übertriebene) Option könnte die Verwendung eines Compilers für eine reduzierte SQL-Sprache sein. So etwas wie JavaCC mit einer modifizierten SQL-Grammatik, die nur SELECT-Anweisungen zulässt. Dann könnten Sie die Abfrage erhalten, sie kompilieren und wenn sie kompiliert ist, können Sie sie ausführen.

Für C# weiß ich Ironie aber nie benutzt.

1voto

BradC Punkte 38356

Mit einer Aktualisierungsanweisung können Sie eine Menge Schaden anrichten.

Ich hatte ein ähnliches Projekt, und unsere Lösung bestand darin, den Benutzer durch einen sehr lästigen Assistenten zu führen, der ihm die Auswahl ermöglicht, aber die Abfrage selbst wird hinter den Kulissen durch den Anwendungscode erstellt. Die Erstellung war sehr mühsam, aber wenigstens hatten wir die Kontrolle über den Code, der schließlich ausgeführt wurde.

0 Stimmen

Re: Beschädigung - es gibt eine Versionskontrolle für die betroffenen Tabellen, so dass jede Beschädigung von Daten rückgängig gemacht werden kann.

1voto

Martin Brown Punkte 23597

Die Frage ist, ob Sie Ihren Nutzern vertrauen. Wenn sich Ihre Benutzer beim System anmelden mussten, Sie HTTPS verwenden und Vorkehrungen gegen XSS-Angriffe getroffen haben, ist SQL Injection ein geringeres Problem. Die Ausführung der Abfragen unter einem eingeschränkten Konto sollte ausreichen, wenn Sie den legitimen Benutzern vertrauen. Ich betreibe MyLittleAdmin seit Jahren im Internet und habe noch nie ein Problem gehabt.

Wenn Sie unter einem ordnungsgemäß eingeschränkten SQL-Konto select convert(varchar(50),0x64726F70207461626C652061) ausführen, kommen Sie nicht sehr weit, und Sie können sich gegen ressourcenintensive Abfragen schützen, indem Sie ein kurzes Timeout für Ihre Datenbankanfragen festlegen. Es könnten zwar immer noch falsche Aktualisierungen vorgenommen werden, aber dann stellt sich wieder die Frage, ob Sie Ihren Benutzern vertrauen.

Sie gehen immer ein Risiko ein, wenn Sie eine Datenbank mit dem Internet verbinden, aber dafür sind ja Backups da.

0 Stimmen

Die Website ist passwortgeschützt, https. Die Abfragen werden mit einem Datenbankbenutzer ausgeführt, der nur die Berechtigungen select table, select view und update table hat. Es wird eine Versionskontrolle für die Daten in der DB selbst geben, so dass falsche Abfragen jederzeit zurückgesetzt werden können.

0 Stimmen

Sie sollten Ihre Frage-Tags aktualisieren, um asp.net oder Website zu lesen, so dass unsere Antworten dann spezifischer sein können.

0 Stimmen

Ich habe die Tags und den ersten Satz der Frage aktualisiert, um dies zu berücksichtigen.

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