Ich habe sowohl meinen Kollegen als auch hier auf SO über die Vorteile der Verwendung von Parametern in SQL-Abfragen, insbesondere in .NET-Anwendungen, gepredigt. Ich bin sogar so weit gegangen, ihnen zu versprechen, Immunität gegen SQL-Injection-Angriffe zu gewähren.
Aber ich frage mich, ob das wirklich stimmt. Gibt es bekannte SQL-Injection-Angriffe, die für eine parametrisierte Abfrage erfolgreich sind? Können Sie zum Beispiel eine Zeichenfolge senden, die einen Pufferüberlauf auf dem Server verursacht?
Es müssen natürlich noch andere Überlegungen angestellt werden, um sicherzustellen, dass eine Webanwendung sicher ist (z. B. das Bereinigen von Benutzereingaben und all diesen Dingen), aber jetzt denke ich an SQL-Injektionen. Ich bin besonders an Angriffen gegen MsSQL 2005 und 2008 interessiert, da dies meine primären Datenbanken sind, aber alle Datenbanken sind interessant.
Bearbeiten: Um zu verdeutlichen, was ich unter Parametern und parametrisierten Abfragen verstehe. Mit Parametern meine ich die Verwendung von "Variablen", anstatt die SQL-Abfrage in einer Zeichenfolge zu erstellen.
Also anstatt dies zu tun:
SELECT * FROM Table WHERE Name = 'a name'
Wir machen das:
SELECT * FROM Table WHERE Name = @Name
und legen Sie dann den Wert des Parameters @Name für das Abfrage- / Befehlsobjekt fest.
quelle
Antworten:
Platzhalter reichen aus, um Injektionen zu verhindern. Möglicherweise sind Sie immer noch offen für Pufferüberläufe, aber das ist eine völlig andere Angriffsart als eine SQL-Injection (der Angriffsvektor wäre keine SQL-Syntax, sondern eine Binärdatei). Da die übergebenen Parameter alle ordnungsgemäß maskiert werden, kann ein Angreifer keine Daten übergeben, die wie "Live" -SQL behandelt werden.
Sie können keine Funktionen in Platzhaltern verwenden, und Sie können keine Platzhalter als Spalten- oder Tabellennamen verwenden, da diese maskiert und als Zeichenfolgenliterale in Anführungszeichen gesetzt werden.
Wenn Sie jedoch Parameter als Teil einer Zeichenfolgenverkettung in Ihrer dynamischen Abfrage verwenden, sind Sie weiterhin anfällig für Injektionen, da Ihre Zeichenfolgen nicht maskiert, sondern wörtlich sind. Die Verwendung anderer Typen für Parameter (z. B. Ganzzahl) ist sicher.
Das heißt, wenn Sie die Verwendung von input verwenden, um den Wert von etwas wie
security_level
festzulegen, kann sich jemand einfach selbst zum Administrator in Ihrem System machen und einen Free-for-All haben. Dies ist jedoch nur eine grundlegende Eingabevalidierung und hat nichts mit SQL-Injection zu tun.quelle
Nein, es besteht immer noch das Risiko einer SQL-Injection, wenn Sie nicht validierte Daten in eine SQL-Abfrage interpolieren.
Abfrageparameter helfen, dieses Risiko zu vermeiden, indem Literalwerte von der SQL-Syntax getrennt werden.
Das ist in Ordnung, aber es gibt andere Zwecke, Daten in eine dynamische SQL-Abfrage zu interpolieren, die keine Abfrageparameter verwenden kann, da es sich nicht um einen SQL-Wert handelt, sondern um einen Tabellennamen, einen Spaltennamen, einen Ausdruck oder eine andere Syntax.
Es spielt keine Rolle, ob Sie gespeicherte Prozeduren verwenden oder dynamische SQL-Abfragen direkt aus dem Anwendungscode ausführen. Das Risiko ist immer noch da.
In diesen Fällen besteht die Abhilfe darin, FIEO nach Bedarf einzusetzen :
Filtereingabe: Überprüfen Sie, ob die Daten wie legitime Ganzzahlen, Tabellennamen, Spaltennamen usw. aussehen, bevor Sie sie interpolieren.
Escape-Ausgabe: In diesem Fall bedeutet "Ausgabe" das Einfügen von Daten in eine SQL-Abfrage. Wir verwenden Funktionen, um Variablen, die als Zeichenfolgenliterale in einem SQL-Ausdruck verwendet werden, so zu transformieren, dass Anführungszeichen und andere Sonderzeichen in der Zeichenfolge maskiert werden. Wir sollten auch Funktionen verwenden, um Variablen zu transformieren, die als Tabellennamen, Spaltennamen usw. verwendet werden. Bei anderen Syntaxen wie dem dynamischen Schreiben ganzer SQL-Ausdrücke ist dies ein komplexeres Problem.
quelle
In diesem Thread scheint es einige Verwirrung über die Definition einer "parametrisierten Abfrage" zu geben.
In Anbetracht der früheren Definition zeigen viele der Links funktionierende Angriffe.
Aber die "normale" Definition ist die letztere. Angesichts dieser Definition kenne ich keinen SQL-Injection-Angriff, der funktionieren würde. Das heißt nicht, dass es keinen gibt, aber ich muss es noch sehen.
Aus den Kommentaren geht hervor, dass ich mich nicht klar genug ausdrücke. Hier ist ein Beispiel, das hoffentlich klarer wird:
Dieser Ansatz ist offen für SQL-Injection
Dieser Ansatz ist für die SQL-Injection nicht offen
quelle
Jeder SQL-Parameter vom Typ String (varchar, nvarchar usw.), der zum Erstellen einer dynamischen Abfrage verwendet wird, ist weiterhin anfällig
Andernfalls sollte die Konvertierung des Parametertyps (z. B. in int, decimal, date usw.) jeden Versuch verhindern, SQL über den Parameter einzufügen
BEARBEITEN: Ein Beispiel, in dem Parameter @ p1 ein Tabellenname sein soll
Wenn @ p1 aus einer Dropdown-Liste ausgewählt ist, handelt es sich um einen potenziellen SQL-Injection-Angriffsvektor.
Wenn @ p1 programmgesteuert formuliert wird, ohne dass der Benutzer eingreifen kann, handelt es sich nicht um einen potenziellen Angriffsvektor für die SQL-Injektion
quelle
Ein Pufferüberlauf ist keine SQL-Injection.
Parametrisierte Abfragen garantieren, dass Sie vor SQL-Injection geschützt sind. Sie garantieren nicht, dass es keine möglichen Exploits in Form von Fehlern in Ihrem SQL Server gibt, aber nichts wird dies garantieren.
quelle
Ihre Daten sind nicht sicher, wenn Sie dynamisches SQL in irgendeiner Form verwenden, da sich die Berechtigungen auf Tabellenebene befinden müssen. Ja, Sie haben die Art und das Ausmaß des Injektionsangriffs durch diese bestimmte Abfrage begrenzt, aber nicht den Zugriff, den ein Benutzer erhalten kann, wenn er oder sie einen Weg in das System findet, und Sie sind für interne Benutzer, die auf das zugreifen, was sie nicht sollten, völlig gefährdet um Betrug zu begehen oder persönliche Informationen zu stehlen, um sie zu verkaufen. Dynamisches SQL jeglicher Art ist eine gefährliche Praxis. Wenn Sie nicht dynamisch gespeicherte Prozesse verwenden, können Sie Berechtigungen auf Prozedurebene festlegen, und kein Benutzer kann etwas anderes tun als das, was durch die Prozesse definiert ist (außer natürlich Systemadministratoren).
quelle
Es ist möglich, dass ein gespeicherter Prozess durch Überlauf / Abschneiden für bestimmte Arten der SQL-Injection anfällig ist. Siehe: Injection Enabled by Data Truncation hier:
http://msdn.microsoft.com/en-us/library/ms161953.aspx
quelle
Denken Sie daran, dass Sie mit Parametern die Zeichenfolge einfach speichern oder den Benutzernamen sagen können, wenn Sie keine Richtlinien haben. "); Tabellenbenutzer löschen; -"
Dies an sich verursacht keinen Schaden, aber Sie wissen besser, wo und wie dieses Datum weiter unten in Ihrer Anwendung verwendet wird (z. B. in einem Cookie gespeichert, später abgerufen, um andere Aufgaben zu erledigen.
quelle
Sie können als Beispiel dynamisches SQL ausführen
quelle