Wie kann Hygiene, die einfachen Anführungszeichen entgeht, durch SQL Injection in SQL Server besiegt werden?
Starten, ausschalten, ich bin mir bewusst, dass parametrisierte Abfragen sind die beste option, aber ich Frage, was macht die Strategie, die ich im folgenden präsentieren anfällig. Leute, die darauf bestehen, die unterhalb Lösung nicht funktioniert, so dass ich am schauen für ein Beispiel, warum es würde nicht.
Wenn dynamische SQL-gebaut wird im code über die folgenden Flucht, bevor Sie gesendet werden, um einen SQL-Server, welche Art von Injektion Sie besiegen kann?
string userInput= "N'" + userInput.Replace("'", "''") + "'"
Eine ähnliche Frage wurde beantwortet hieraber ich glaube nicht, dass jeder der Antworten sind hier anwendbar.
Flucht das einfache Anführungszeichen mit einem "\" ist nicht möglich, in SQL Server.
Ich glaube SQL Schmuggel mit Unicode (skizziert hier), würde konterkariert werden durch die Tatsache, dass die Zeichenfolge, die produziert wird, der markiert ist als Unicode, die von dem N vor dem Apostroph. Soweit ich weiß, gibt es keine andere Zeichensätze, dass der SQL-Server würde automatisch übersetzen, um ein einziges Zitat. Ohne ein unescaped einzige Zitat, ich glaube nicht, dass die Injektion ist möglich.
Ich glaube nicht, dass String Abschneiden ist eine praktikable Vektor. SQL Server sicherlich nicht tun werden die abgeschnitten, da die max Größe für ein nvarchar
2 GB laut microsoft. Eine 2-GB-string ist nicht machbar in den meisten Situationen, und unmöglich in meiner.
Zweiter Ordnung Injektion könnte möglich sein, aber ist es möglich, wenn:
- Alle Daten gehen in die Datenbank bereinigt mithilfe der oben beschriebenen Methode
- Werte aus der Datenbank sind nie angehängt, die in der dynamischen SQL (warum würden Sie jemals tun, anyways, wenn man nur auf die Tabelle mit dem Wert in der statische Teil dynamischer SQL-string?).
Ich bin nicht was darauf hindeutet, dass dies besser ist, oder als eine alternative zur Verwendung von parametrisierten Abfragen, aber ich möchte wissen, wie das, was ich dargelegt ist anfällig. Irgendwelche Ideen?
InformationsquelleAutor der Frage GBleaney | 2013-03-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es ein paar Fälle, in denen diese escape-Funktion fehl. Der offensichtlichste ist, wenn ein einzelnes Zitat nicht verwendet:
In diesem Fall, können Sie "brechen aus" mit einer double-quote, um ein back-tick. Im letzten Fall gibt es nichts zu "break out", so kann man nur schreiben
1 union select password from users--
oder was auch immer sql Nutzlast der Angreifer wünscht.Den nächsten Zustand, in dem Sie diese escape-Funktion fehl, wenn Sie einen sub-string nach dem string maskiert (und ja ich haben Schwachstellen, wie dies in der wild):
In diesem Fall der Benutzername
abcdefgji'
wird verwandelt werden inabcdefgji''
durch die escape-Funktion und wandte sich dann wieder inabcdefgji'
durch die Berücksichtigung der sub-string. Dies kann ausgenutzt werden, indem die Kennwort-Wert in einer beliebigen sql-Anweisung, in diesem Fallor 1=1--
würde interpretiert werden als sql und der username würde interpretiert werden alsabcdefgji'' and password=
. Die resultierende Abfrage ist wie folgt:T-SQL und andere fortgeschrittene sql-injection-Techniken, bei denen schon erwähnt. Advanced SQL Injection In SQL Server Applications ist eine große Papier-und Sie sollten es Lesen, wenn Sie nicht bereits getan haben.
Das Letzte Problem, unicode-Attacken. Diese Klasse von Sicherheitsanfälligkeiten, die entsteht, weil die escape-Funktion ist nicht bekannt, mulit-byte-Codierung, und dies kann die von einem Angreifer verwendet, um zu "konsumieren" das escape-Zeichen. Voranstellen eines "N", um die Zeichenfolge wird nicht helfen, da dies keinen Einfluss auf den Wert der Multibyte-chars später in der Zeichenfolge. Jedoch, diese Art von Angriff ist sehr ungewöhnlich, weil die Datenbank muss so konfiguriert werden, akzeptieren GBK unicode-strings (und ich bin nicht sicher, dass MS-SQL kann).
Second-Order-code-Injektion ist immer noch möglich, diesen Angriff Muster ist erstellt durch das Vertrauen, die einem Angreifer Datenquellen. Die Flucht wird zum darstellen von steuerzeichen, da Ihre Zeichen-literal. Wenn der Entwickler vergisst, zu entkommen, ein Wert, erhalten aus einer
select
und verwendet dann diesen Wert in einer anderen Abfrage, dann bam die Angreifer haben ein Zeichen-literal einziges Zitat zur Verfügung stellen.Test alles, Vertrauen nichts.
InformationsquelleAutor der Antwort rook
Einige zusätzliche Bestimmungen, dein Ansatz oben ist nicht anfällig für SQL-injection. Der wichtigste Vektor des Angriffs zu betrachten ist SQL-Schmuggel. SQL Schmuggel tritt auf, wenn ähnliche unicode-Zeichen übersetzt werden, in einer unerwarteten Art und Weise (z.B. ` ändern ' ). Es gibt mehrere Orte, wo ein application-stack sein könnte anfällig für SQL-Schmuggel.
Nicht die Programmiersprache die Verarbeitung von unicode-Zeichenfolgen entsprechend? Wenn die Sprache nicht unicode-fähig, können mis-identifizieren, ein byte in ein unicode-Zeichen als ein einziges Zitat, und es entgehen.
Ist der client-Datenbank-Bibliothek (z.B. ODBC, etc) die Verarbeitung von unicode-Zeichenfolgen entsprechend? System.Daten.SqlClient in der .Net framework nicht, aber wie wäre es mit alten Bibliotheken aus dem windows 95-ära? Dritter ODBC-Bibliotheken tatsächlich existieren. Was passiert, wenn der ODBC-Treiber keine Unterstützung für unicode in den query-string?
Hat die DB die Eingaben verarbeiten, richtig? Moderne Versionen von SQL immun sind davon ausgegangen, dass Sie N", aber was ist mit SQL 6.5? SQL 7.0? Ich bin mir nicht bewusst, irgendwelche besonderen Schwachstellen, aber diese war nicht auf dem radar für die Entwickler in den 1990er Jahren.
Buffer overflows? Ein weiteres Anliegen ist, dass die Zeichenfolge in Anführungszeichen ist länger als die ursprüngliche Zeichenfolge. In welcher version von Sql Server wurde das 2 GB-limit für die Eingabe eingeführt? Vor, dass das, was war die Grenze? Auf älteren Versionen von SQL, was passiert, wenn eine Abfrage den Grenzwert überschritten? Irgendwelche Grenzen gibt es auf der Länge von einer Abfrage aus der Sicht der Netzwerk-Bibliothek? Oder auf der Länge der Zeichenfolge in der Programmiersprache?
Sind da, jede Sprache, Einstellungen, Auswirkungen auf den Vergleich verwendet in der Replace () - Funktion? .Net immer ein binärer Vergleich für die Replace () - Funktion. Wird das immer der Fall sein? Was passiert, wenn eine zukünftige version .NET unterstützt überschreiben, Verhalten an der app.config-Ebene? Was, wenn wir verwendet ein regexp-anstelle von Replace (), um ein einzelnes Zitat einfügen? Ist der computer das Gebietsschema Einstellungen wirken sich in diesem Vergleich? Wenn eine änderung im Verhalten auftreten, ist es vielleicht nicht anfällig für sql-injection, jedoch kann es versehentlich bearbeitet die Zeichenfolge ändern, indem Sie eine uni-code-Zeichen, das aussah, wie ein einziges Zitat in einem einzigen zitieren, bevor es überhaupt erreicht die DB.
So, wenn Sie das System benutzen.String.Replace () - Funktion in C# auf die aktuelle version .Netto mit dem built-in "SqlClient" - Bibliothek gegen eine aktuelle (2005-2012) version von SQL server, dann ist dein Ansatz ist nicht anfällig. Wie man Dinge ändert, dann werden keine Versprechungen gemacht werden können. Die parametrisierte Abfrage Ansatz ist der richtige Ansatz für Effizienz, Leistung und (in einigen Fällen) für Sicherheit.
WARNUNG Die obigen Ausführungen sind nicht als Empfehlung von dieser Technik. Es gibt einige andere sehr gute Gründe, warum dies der falsche Ansatz zur Generierung von SQL. Jedoch, Detaillierung, Sie ist außerhalb des Gültigkeitsbereichs für diese Frage.
VERWENDEN SIE DIESES VERFAHREN NICHT FÜR DIE NEUE ENTWICKLUNG.
VERWENDEN SIE DIESES VERFAHREN NICHT FÜR DIE NEUE ENTWICKLUNG.
VERWENDEN SIE DIESES VERFAHREN NICHT FÜR DIE NEUE ENTWICKLUNG.
InformationsquelleAutor der Antwort StrayCatDBA
Mit dem Abfrage-Parameter ist einfacher, besser und schneller als die Flucht Anführungszeichen.
Re Ihren Kommentar, ich sehe, dass Sie bestätigten, dass die Parametrisierung, aber es verdient Betonung. Warum würden Sie wollen, verwenden Sie die Flucht, wenn Sie parametrisieren?
In Advanced SQL Injection In SQL Server ApplicationsSuche nach dem Wort "ersetzen" in den text, und Lesen Sie einige Beispiele, wo Entwickler versehentlich erlaubt SQL-injection-Angriffe auch nach der Flucht von Benutzereingaben.
Gibt eine Kante Fall, wo die Flucht Zitate mit
\
Ergebnisse in eine Sicherheitsanfälligkeit, weil die\
wird die Hälfte der ein gültiges Multibyte-Zeichen in einem Charakter-sets. Aber dies ist nicht anwendbar auf Ihren Fall zu, da\
ist nicht die Flucht Charakter.Wie andere haben darauf hingewiesen, Sie können auch hinzufügen dynamischer Inhalte, um Ihre SQL für etwas anderes als ein string-literal oder Datum-literal. Tabelle oder Spalte Bezeichner getrennt durch
"
in SQL, oder[
]
im Microsoft/Sybase. SQL-Schlüsselwörter natürlich nicht irgendwelche Trennzeichen. Für diese Fälle empfehle ich whitelisting die Werte zu interpolieren.Quintessenz ist, dass die Flucht ist eine wirksame Verteidigung, wenn Sie sicherstellen können, dass Sie es konsequent tun. Das ist die Gefahr: dass einer der Entwickler-team auf Ihre Bewerbung weglassen könnte, einen Schritt zu tun und einige string-interpolation nicht sicher ist.
Natürlich, das gleiche gilt für die anderen Methoden, wie der Parametrisierung. Sie sind nur wirksam, wenn Sie Sie konsequent. Aber ich finde es einfacher, schneller, Parameter zu verwenden, als die, um herauszufinden, die richtige Art von Flucht. Und die Entwickler sind eher zu verwenden, eine Methode, die bequem ist und nicht langsam nach unten.
InformationsquelleAutor der Antwort Bill Karwin
SQL-injection auftreten, wenn Benutzer gelieferten Eingaben werden als Befehle interpretiert. Hier Befehl bedeutet, dass alles, was ist nicht so auszulegen, als eine anerkannte Datentyp literal.
Nun, wenn Sie die Eingabe des Benutzers nur in Daten-Literale, die speziell nur in string-literalen, die Benutzer-Eingabe würde nur interpretiert werden, als etwas anderes als string-Daten, wenn es in der Lage sein würde, zu verlassen, das string-literal Kontext. Für Zeichenfolgen-oder Unicode-string-Literale, es ist die einzige Anführungszeichen umschließt die wörtliche Daten, während eingebettetes einfaches Anführungszeichen vertreten sein müssen, mit zwei einzelnen Anführungszeichen.
So zu verlassen, ein string-literal Kontext, würde man brauchen, um die Versorgung ein einzelnes Anführungszeichen (sic) als zwei einzelne Anführungszeichen werden interpretiert als string-literal Daten und nicht als string-literal Trennzeichen am Ende.
Also, wenn Sie ersetzen jedes einzelne Anführungszeichen in der vom Benutzer bereitgestellten Daten durch zwei einfache Anführungszeichen, wird es für den Benutzer unmöglich, Sie zu verlassen, das string-literal Kontext.
InformationsquelleAutor der Antwort Gumbo
SQL-Injektion auftreten können, die über unicode. Wenn die web-app eine URL wie diese:
http://mywebapp/widgets/?Code=ABC
generiert SQL wie
select * from widgets where Code = 'ABC'
aber ein hacker in dieses:
http://mywebapp/widgets/?Code=ABC%CA%BC;drop Tabelle widgets--
SQL Aussehen wird
select * from widgets where Code = 'ABC';drop table-widgets--'
und SQL Server laufen wird, werden zwei SQL-Anweisungen. Eine zu tun, das wählen und tun die Tropfen.
Ihr code wahrscheinlich konvertiert url-kodierte %CA%BC in unicode U02BC was ist ein "Modifier letter apostrophe". Die Ersetzen-Funktion in .Net wird NICHT behandeln, als ein einziges Zitat. Jedoch Microsoft SQL Server behandelt es wie ein einziges Zitat. Hier ist ein Beispiel, wird wahrscheinlich erlauben SQL-Injection:
InformationsquelleAutor der Antwort Rob Kraft
Gibt es wohl keine 100% sichere Weg, wenn du die string-Verkettung. Was Sie tun können, ist zu versuchen, die Daten zu überprüfen geben Sie für jeden parameter, und wenn alle Parameter übergeben diese überprüfung dann gehen Sie vor mit der Ausführung. Zum Beispiel, wenn Ihre parameter werden sollte Typ int und du bist immer etwas, das kann nicht in int konvertiert, dann einfach ablehnen.
Das funktioniert nicht, aber wenn Sie akzeptieren, nvarchar-Parameter.
Als andere bereits hingewiesen. Der sicherste Weg ist die Verwendung von parametrisierten Abfragen.
InformationsquelleAutor der Antwort George Wesley