Stimmt es, dass gespeicherte Prozeduren SQL-Injection-Angriffe auf PostgreSQL-Datenbanken verhindern? Ich habe ein wenig nachgeforscht und festgestellt, dass SQL Server, Oracle und MySQL nicht gegen SQL Injection sicher sind, auch wenn wir nur gespeicherte Prozeduren verwenden. Dieses Problem existiert jedoch nicht in PostgreSQL.
Verhindert die Implementierung der gespeicherten Prozedur im PostgreSQL-Kern SQL-Injection-Angriffe oder handelt es sich um etwas anderes? Oder ist PostgreSQL auch für SQL-Injection anfällig, selbst wenn wir nur gespeicherte Prozeduren verwenden? Wenn ja, zeigen Sie mir bitte ein Beispiel (z. B. Buch, Website, Papier usw.).
postgresql
security
sql-injection
Am1rr3zA
quelle
quelle
Antworten:
Nein, gespeicherte Prozeduren verhindern die SQL-Injektion nicht. Hier ist ein aktuelles Beispiel (von einer Inhouse-App, die von jemandem erstellt wurde, an dem ich arbeite) einer gespeicherten Prozedur, die leider SQL-Injection zulässt:
Dieser SQL Server Code:
ungefähr äquivalent zu postgres:
Die Idee des Entwicklers war es, ein vielseitiges Suchverfahren zu erstellen. Das Ergebnis ist jedoch, dass die WHERE-Klausel alles enthalten kann, was der Benutzer möchte, und so den Besuch von kleinen Bobby Tables ermöglicht .
Ob Sie SQL-Anweisungen oder gespeicherte Prozeduren verwenden, spielt keine Rolle. Entscheidend ist, ob Ihr SQL-Code Parameter oder verkettete Zeichenfolgen verwendet. Parameter verhindern SQL-Injection; Verkettete Zeichenfolgen ermöglichen die SQL-Injektion.
quelle
SQL-Injection-Angriffe sind Angriffe, bei denen nicht vertrauenswürdige Eingaben direkt an Abfragen angehängt werden, sodass der Benutzer beliebigen Code effektiv ausführen kann, wie in diesem kanonischen XKCD-Comic dargestellt.
So bekommen wir die Situation:
Gespeicherte Prozeduren sind im Allgemeinen eine gute Abwehr gegen SQL-Injection-Angriffe, da die eingehenden Parameter niemals analysiert werden.
In einer gespeicherten Prozedur sehen in den meisten DBs (und Programmen, die vorkompilierten Abfragen zählen als gespeicherte Prozeduren) wie folgt aus:
Wenn das Programm dann Zugriff wünscht, ruft es
foo(userInput)
das Ergebnis auf und ruft es glücklich ab.Eine gespeicherte Prozedur ist keine magische Verteidigung gegen SQL-Injection, da Benutzer durchaus in der Lage sind, fehlerhafte gespeicherte Prozeduren zu schreiben . Vorkompilierte Abfragen, seien sie in der Datenbank oder im Programm gespeichert, sind jedoch viel schwieriger zu öffnen, wenn Sie verstehen, wie SQL-Injection funktioniert.
Sie können mehr über SQL-Injection lesen:
quelle
Ja, bis zu einem gewissen Grad.
Gespeicherte Prozeduren allein verhindern SQL Injection nicht.
Lassen Sie mich zuerst über SQL Injection von OWASP zitieren
Sie müssen Benutzereingaben bereinigen und SQL-Anweisungen nicht verketten, auch wenn Sie gespeicherte Prozeduren verwenden.
Jeff Attwood erklärte die Konsequenzen der Verkettung von SQL in " Gib mir parametrisiertes SQL oder gib mir den Tod "
Das Folgende ist der interessante Cartoon, der mir in den Sinn kommt, wenn ich SQL Injection höre. Ich glaube, Sie haben den Punkt verstanden :-)
Schauen Sie sich das SQL Injection Prevention Cheat Sheet an , die Methoden zur Vorbeugung werden genau erklärt ...
quelle
Die Verkettung von Zeichenfolgen ist die Ursache für SQL Injection. Dies wird durch Parametrierung vermieden.
Gespeicherte Prozeduren fügen eine zusätzliche Sicherheitsebene hinzu, indem sie beim Verketten ungültige Syntax erzwingen. Sie sind jedoch nicht "sicherer", wenn Sie beispielsweise dynamisches SQL verwenden.
Der obige Code wird also durch die Verkettung dieser Zeichenfolgen verursacht
exec sp_GetUser '
x' AND 1=(SELECT COUNT(*) FROM Client); --
' , '
monkey
'
Dies führt zum Glück zu einer ungültigen Syntax
Parametrisierung würde es geben
Das heisst
@UserName
=x' AND 1=(SELECT COUNT(*) FROM Client); --
@Password
=monkey
Im obigen Code erhalten Sie keine Zeilen, da ich davon ausgehe, dass Sie keinen Benutzer haben
x' AND 1=(SELECT COUNT(*) FROM Client); --
Wenn der gespeicherte Prozess so aussah (mithilfe von verkettetem dynamischem SQL ), lässt Ihr parametrisierter gespeicherter Prozessaufruf weiterhin SQL Injection zu
Wie gezeigt, ist die Verkettung von Zeichenfolgen der Hauptfeind für die SQL-Injektion
Gespeicherte Prozeduren fügen Kapselung, Transaktionsbehandlung, reduzierte Berechtigungen usw. hinzu, können jedoch weiterhin für die SQL-Injektion missbraucht werden.
Weitere Informationen zur Parametrisierung finden Sie unter Stapelüberlauf
quelle
„SQL - Injection - Angriffe passieren , wenn eine Benutzereingabe ist falsch codiert. In der Regel die Benutzereingabe einig Daten der Benutzer mit ihrer Abfrage, dh Werte in dem sendet
$_GET
,$_POST
,$_COOKIE
,$_REQUEST
, oder$_SERVER
Arrays. Allerdings Benutzereingabe kann auch kommen aus einer Vielzahl von anderen Quellen wie Sockets, entfernte Websites, Dateien usw. Daher sollten Sie wirklich alles außer Konstanten (wie'foobar'
) als Benutzereingabe behandeln . "Ich habe mich in letzter Zeit eingehend mit diesem Thema befasst und möchte mit anderen sehr interessantes Material teilen, um diesen Beitrag für alle vollständiger und lehrreicher zu machen.
Von YouTube
Aus Wikipedia
Aus OWASP
Aus dem PHP-Handbuch
Von Microsoft und Oracle
Paketüberfluss
SQL-Injektionsscanner
quelle
Gespeicherte Prozeduren verhindern SQL-Injection nicht auf magische Weise, aber sie machen es viel einfacher, dies zu verhindern. Alles, was Sie tun müssen, ist etwas wie das Folgende (Postgres-Beispiel):
Das ist es! Das Problem tritt nur beim Bilden einer Abfrage über Zeichenfolgenverkettung (dh dynamisches SQL) auf, und selbst in diesen Fällen können Sie möglicherweise eine Bindung herstellen! (Kommt auf die Datenbank an.)
So vermeiden Sie SQL-Injection in Ihrer dynamischen Abfrage:
Schritt 1) Fragen Sie sich, ob Sie wirklich eine dynamische Abfrage benötigen. Wenn Sie Strings zusammenhalten, nur um den Eingang zu setzen, dann machen Sie es wahrscheinlich falsch. (Es gibt Ausnahmen zu dieser Regel. Eine Ausnahme betrifft das Melden von Abfragen in einigen Datenbanken. Möglicherweise treten Leistungsprobleme auf, wenn Sie nicht zwingen, bei jeder Ausführung eine neue Abfrage zu kompilieren. Ermitteln Sie dieses Problem jedoch, bevor Sie sich damit befassen.) )
Schritt 2) Ermitteln Sie die richtige Methode zum Festlegen der Variablen für Ihr bestimmtes RDBMS. Zum Beispiel können Sie in Oracle Folgendes tun (aus ihren Dokumenten zitieren):
Hier verketten Sie die Eingabe noch nicht. Sie sind sicher bindend! Hurra!
Wenn Ihre Datenbank so etwas nicht unterstützt (hoffentlich ist keine von ihnen immer noch so schlecht, aber ich würde mich nicht wundern) - oder wenn Sie Ihre Eingaben immer noch wirklich verketten müssen (wie im "manchmal" Fall, wenn Sie Abfragen melden, als Ich habe oben angedeutet), dann müssen Sie eine ordnungsgemäße Escape-Funktion verwenden. Schreib es nicht selbst. Beispielsweise bietet postgres die Funktion quote_literal (). Du würdest also laufen:
Auf diese Weise, wenn in_name etwas abwegiges wie '[snip] oder 1 = 1' ist (der Teil "oder 1 = 1" bedeutet, dass alle Zeilen ausgewählt werden, sodass der Benutzer die Gehälter sieht, die er nicht sehen sollte!), Speichert quote_literal Ihren Hintern durch Die resultierende Zeichenfolge erstellen:
Es werden keine Ergebnisse gefunden (es sei denn, Sie haben Mitarbeiter mit wirklich verrückten Namen.)
Das ist der Kern davon! Lassen Sie mich nun einen Link zu einem klassischen Post von Oracle-Guru Tom Kyte zum Thema SQL-Injection hinterlassen, um den Punkt nach Hause zu bringen: Linky
quelle
quote_ident()
- aber im Allgemeinen besteht die einfachste Möglichkeit, injektionssicheres dynamisches SQL zu schreiben, darin,format()
die Platzhalter%I
für Bezeichner und%L
für Literale zu verwenden und zu verwenden . Auf diese Weise ist die SQL viel lesbarer als die entsprechende Version mit||
undquote_....()
Funktionen