Kann ich mich vor SQL-Injection schützen, indem ich einfache Anführungszeichen und umgebende Benutzereingaben mit einfachen Anführungszeichen verbinde?

139

Mir ist klar, dass parametrisierte SQL-Abfragen die optimale Methode sind, um Benutzereingaben zu bereinigen, wenn Abfragen erstellt werden, die Benutzereingaben enthalten. Ich frage mich jedoch, was falsch daran ist, Benutzereingaben zu übernehmen und einfache Anführungszeichen zu umgehen und die gesamte Zeichenfolge mit einfachen Anführungszeichen zu umgeben. Hier ist der Code:

sSanitizedInput = "'" & Replace(sInput, "'", "''") & "'"

Jedes einfache Anführungszeichen, das der Benutzer eingibt, wird durch doppelte einfache Anführungszeichen ersetzt, wodurch die Möglichkeit des Benutzers, die Zeichenfolge zu beenden, entfällt. Alle anderen eingegebenen Zeichen wie Semikolons, Prozentzeichen usw. sind Teil der Zeichenfolge und nicht tatsächlich als Teil des Befehls ausgeführt.

Wir verwenden Microsoft SQL Server 2000, für das das einfache Anführungszeichen meines Erachtens das einzige Zeichenfolgenbegrenzer und die einzige Möglichkeit ist, dem Zeichenfolgenbegrenzer zu entkommen. Daher gibt es keine Möglichkeit, etwas auszuführen, das der Benutzer eingibt.

Ich sehe keine Möglichkeit, einen SQL-Injection-Angriff dagegen zu starten, aber mir ist klar, dass, wenn dies so kugelsicher wäre, wie es mir scheint, jemand anderes bereits daran gedacht hätte und es gängige Praxis wäre.

Was ist los mit diesem Code? Gibt es eine Möglichkeit, einen SQL-Injection-Angriff nach dieser Desinfektionstechnik durchzuführen? Eine Benutzereingabe, die diese Technik ausnutzt, wäre sehr hilfreich.


AKTUALISIEREN:

Ich kenne immer noch keine Möglichkeit, einen SQL-Injection-Angriff gegen diesen Code effektiv zu starten. Einige Leute schlugen vor, dass ein Backslash einem einfachen Anführungszeichen entgehen und das andere die Zeichenfolge beenden würde, damit der Rest der Zeichenfolge als Teil des SQL-Befehls ausgeführt wird, und mir ist klar, dass diese Methode funktionieren würde, um SQL einzufügen eine MySQL-Datenbank, aber in SQL Server 2000 ist die einzige Möglichkeit (die ich gefunden habe), einem einfachen Anführungszeichen zu entkommen, ein anderes einfaches Anführungszeichen; Backslashes machen das nicht.

Und wenn es keine Möglichkeit gibt, das Entkommen des einfachen Anführungszeichens zu stoppen, wird keine der restlichen Benutzereingaben ausgeführt, da alle als eine zusammenhängende Zeichenfolge verwendet werden.

Ich verstehe, dass es bessere Möglichkeiten gibt, Eingaben zu bereinigen, aber ich bin wirklich mehr daran interessiert zu erfahren, warum die oben angegebene Methode nicht funktioniert. Wenn jemand einen bestimmten Weg kennt, um einen SQL-Injection-Angriff gegen diese Desinfektionsmethode durchzuführen, würde ich ihn gerne sehen.

Patrick
quelle
17
@BryanH Zuzugeben, nicht zu verstehen, wie die allgemein akzeptierte Weisheit für einen bestimmten Fall gilt, und nach einem Beispiel für einen solchen speziellen Fall zu fragen, ist keine Hybris, sondern Demut. Sich zu ärgern, wenn jemand nach einem Beispiel fragt, warum die allgemein akzeptierte Weisheit richtig ist, könnte dagegen arrogant wirken. Das Denken anhand spezifischer Beispiele ist oft eine gute Möglichkeit, Nachforschungen anzustellen und zu lernen. Die Art und Weise, wie das OP diesen Zweifel umging, war sehr nützlich für mein Verständnis des Themas, insbesondere als er die Antwort erklärte, die er fand.
SantiBailors
@patrik Ich bin gerade darauf gestoßen, als ich an demselben Code arbeite, aber versuche, der Zeichenfolge zu entkommen und eine Abfrage zu verschachteln. Hast du es jemals herausgefunden?
3therk1ll
1
@ 3therk1ll es ist am besten nicht zu versuchen, Sie sind besser dran mit parametrisiertem SQL: blog.codinghorror.com/…
Patrick
@Patrick, ich nähere mich dem aus der Perspektive des Angreifers!
3therk1ll

Antworten:

87

Zuallererst ist es nur eine schlechte Übung. Eine Eingabevalidierung ist immer notwendig, aber auch immer zweifelhaft.
Schlimmer noch, die Validierung der Blacklist ist immer problematisch. Es ist viel besser, explizit und genau zu definieren, welche Werte / Formate Sie akzeptieren. Zugegeben, das ist nicht immer möglich - aber bis zu einem gewissen Grad muss es immer getan werden.
Einige Forschungsarbeiten zu diesem Thema:

Der Punkt ist, dass jede Blacklist, die Sie erstellen (und zu zulässige Whitelists), umgangen werden kann. Der letzte Link zu meinem Artikel zeigt Situationen, in denen sogar das Entkommen von Zitaten umgangen werden kann.

Auch wenn diese Situationen nicht auf Sie zutreffen, ist es immer noch eine schlechte Idee. Wenn Ihre App nicht trivial klein ist, müssen Sie sich außerdem um die Wartung und möglicherweise um ein gewisses Maß an Governance kümmern: Wie stellen Sie sicher, dass sie jederzeit und überall richtig ausgeführt wird?

Der richtige Weg, es zu tun:

  • Whitelist-Validierung: Typ, Länge, Format oder akzeptierte Werte
  • Wenn Sie auf die schwarze Liste setzen möchten, fahren Sie fort. Das Entkommen von Zitaten ist gut, aber im Kontext der anderen Abschwächungen.
  • Verwenden Sie Befehls- und Parameterobjekte, um sie vorzubereiten und zu validieren
  • Rufen Sie nur parametrisierte Abfragen auf.
  • Besser noch, verwenden Sie ausschließlich gespeicherte Prozeduren.
  • Vermeiden Sie die Verwendung von dynamischem SQL und verwenden Sie keine Zeichenfolgenverkettung, um Abfragen zu erstellen.
  • Wenn Sie SPs verwenden, können Sie die Berechtigungen in der Datenbank auch darauf beschränken, nur die erforderlichen SPs auszuführen und nicht direkt auf Tabellen zuzugreifen.
  • Sie können auch leicht überprüfen, ob die gesamte Codebasis nur über SPs auf die Datenbank zugreift ...
AviD
quelle
2
Bei korrekter Verwendung können dynamische SQL- und Zeichenfolgenverkettung sicher mit parametrisierten Abfragen verwendet werden (dh mit sp_executesqlanstelle von EXEC). Das heißt, Sie können Ihre SQL-Anweisung dynamisch generieren, solange der verkettete Text nicht vom Benutzer stammt. Dies hat auch Leistungsvorteile; sp_executesqlunterstützt das Caching.
Brian
2
@ Brian, na duh :). Aber wie oft sehen Sie in Wirklichkeit Programmierer, die das tun? Darüber hinaus erfordert das typische Szenario, in dem dynamisches SQL "benötigt" wird, die Benutzereingabe als Teil der Abfrage (angeblich). Wenn Sie sp_executesql ausführen könnten, würden Sie (normalerweise) das dynamische SQL überhaupt nicht benötigen.
AviD
Endlich stieß ich auf eine Situation, in der mir klar wurde, dass es möglich ist, Unicode zu verwenden, um sich am String-Ersatz vorbei zu schleichen. Der Eingabetext wurde in Word eingegeben, wodurch das Apostroph von der geradlinigen Version in ein "lockiges" Apostroph (das eher wie ein Komma aussieht) geändert wurde, das von der Zeichenfolgenersetzung nicht betroffen war, aber von SQL als Zeichenfolgenbegrenzer behandelt wurde Server. Vielen Dank für die Antwort AviD (und alle anderen)!
Patrick
1
@ ElRonnoco sicher, aber ich schätze das nicht ein , da ich es öfter in freier Wildbahn gesehen habe, als Sie denken ...
AviD
1
@AviD Ich habe den Link zum SQL Smuggling PDF, den Sie geschrieben haben, auf die einzige Version aktualisiert, die ich online finden konnte. Bitte teilen Sie uns mit, ob es einen anderen Speicherort für Ihr Papier gibt.
Michael Fredrickson
41

Okay, diese Antwort bezieht sich auf die Aktualisierung der Frage:

"Wenn jemand einen bestimmten Weg kennt, um einen SQL-Injection-Angriff gegen diese Desinfektionsmethode durchzuführen, würde ich ihn gerne sehen."

Abgesehen davon, dass der MySQL-Backslash nicht mehr angezeigt wird - und wenn man bedenkt, dass es sich tatsächlich um MSSQL handelt, gibt es tatsächlich drei Möglichkeiten, wie SQL Ihren Code weiterhin einfügt

sSanitizedInput = "'" & Replace (sInput, "'", "''") & "'"

Berücksichtigen Sie, dass diese nicht alle jederzeit gültig sind und stark von Ihrem tatsächlichen Code abhängen:

  1. SQL-Injection zweiter Ordnung - Wenn eine SQL-Abfrage basierend auf Daten neu erstellt wird, die nach dem Escapezeichen aus der Datenbank abgerufen wurden dem Escape-Vorgang , werden die Daten ohne Verkettung verkettet und können indirekt mit SQL injiziert werden. Sehen
  2. String-Kürzung - (etwas komplizierter) - Szenario: Sie haben zwei Felder, z. B. einen Benutzernamen und ein Kennwort, und SQL verkettet beide. Und beide Felder (oder nur das erste) haben eine harte Längenbeschränkung. Beispielsweise ist der Benutzername auf 20 Zeichen begrenzt. Angenommen, Sie haben diesen Code:
username = left(Replace(sInput, "'", "''"), 20)

Was Sie dann erhalten, ist der Benutzername, der maskiert und dann auf 20 Zeichen gekürzt wurde. Das Problem hier - ich werde mein Zitat in das 20. Zeichen (z. B. nach 19 a) stecken, und Ihr entkommenes Zitat wird gekürzt (im 21. Zeichen). Dann die SQL

sSQL = "select * from USERS where username = '" + username + "'  and password = '" + password + "'"

In Kombination mit dem oben genannten fehlerhaften Benutzernamen befindet sich das Kennwort bereits außerhalb der Anführungszeichen und enthält nur die Nutzdaten direkt.
3. Unicode-Schmuggel - In bestimmten Situationen ist es möglich, ein übergeordnetes Unicode-Zeichen zu übergeben, das wie ein Zitat aussieht , es aber nicht ist - bis es in die Datenbank gelangt, wo es plötzlich ist . Da es sich bei der Validierung nicht um ein Zitat handelt, wird es einfach durchlaufen ... Weitere Informationen finden Sie in meiner vorherigen Antwort und einen Link zur ursprünglichen Forschung.

AviD
quelle
28

Kurz gesagt: Stellen Sie niemals Fragen, die sich selbst entziehen. Du wirst bestimmt etwas falsch machen. Verwenden Sie stattdessen parametrisierte Abfragen. Wenn Sie dies aus irgendeinem Grund nicht tun können, verwenden Sie eine vorhandene Bibliothek, die dies für Sie erledigt. Es gibt keinen Grund, es selbst zu tun.

Nick Johnson
quelle
2
Was ist, wenn Sie sich mit so etwas wie "Google Fusion-Tabellen" befassen müssen, bei denen afaik keine Abstraktionsbibliothek verfügbar ist, die ihren Dialekt unterstützt? Was würdest du vorschlagen?
Systempuntoout
20

Mir ist klar, dass dies eine lange Zeit ist, nachdem die Frage gestellt wurde, aber ..

Eine Möglichkeit, einen Angriff auf die Prozedur "Zitat das Argument" zu starten, ist das Abschneiden von Zeichenfolgen. Laut MSDN wird in SQL Server 2000 SP4 (und SQL Server 2005 SP1) eine zu lange Zeichenfolge stillschweigend abgeschnitten.

Wenn Sie eine Zeichenfolge zitieren, wird die Zeichenfolge größer. Jeder Apostroph wird wiederholt. Dies kann dann verwendet werden, um Teile des SQL aus dem Puffer zu verschieben. So können Sie Teile einer where-Klausel effektiv entfernen.

Dies ist wahrscheinlich vor allem in einem Szenario mit einer Benutzeradministrationsseite nützlich, in dem Sie die Anweisung "update" missbrauchen könnten, um nicht alle Überprüfungen durchzuführen, die sie durchführen sollte.

Wenn Sie sich also dazu entschließen, alle Argumente zu zitieren, stellen Sie sicher, dass Sie wissen, was mit den Zeichenfolgengrößen geschieht, und sorgen Sie dafür, dass Sie nicht auf Kürzungen stoßen.

Ich würde empfehlen, mit Parametern zu gehen. Immer. Ich wünschte nur, ich könnte das in der Datenbank durchsetzen. Und als Nebeneffekt erhalten Sie mit größerer Wahrscheinlichkeit bessere Cache-Treffer, da mehr Aussagen gleich aussehen. (Dies traf sicherlich auf Oracle 8 zu.)

Jørn Jensen
quelle
1
Nach dem Posten habe ich beschlossen, dass der Beitrag von AviD dies ausführlicher behandelt. Hoffentlich hilft mein Beitrag noch jemandem.
Jørn Jensen
10

Ich habe diese Technik verwendet, wenn es um die erweiterte Suche ging, bei der das Erstellen einer Abfrage von Grund auf die einzig praktikable Antwort war. (Beispiel: Ermöglichen Sie dem Benutzer die Suche nach Produkten basierend auf einer unbegrenzten Anzahl von Einschränkungen für Produktattribute, wobei Spalten und ihre zulässigen Werte als GUI-Steuerelemente angezeigt werden, um den Lernschwellenwert für Benutzer zu verringern.)

An sich ist es sicher AFAIK. Wie ein anderer Antwortender betonte, müssen Sie sich möglicherweise auch mit dem Entweichen von Rücktasten befassen (allerdings nicht, wenn Sie die Abfrage zumindest mit ADO oder ADO.NET an SQL Server übergeben - kann nicht für alle Datenbanken oder Technologien bürgen).

Der Haken ist, dass Sie wirklich sicher sein müssen, welche Zeichenfolgen Benutzereingaben enthalten (immer potenziell böswillig) und welche Zeichenfolgen gültige SQL-Abfragen sind. Eine der Fallen ist, wenn Sie Werte aus der Datenbank verwenden - wurden diese Werte ursprünglich vom Benutzer bereitgestellt? Wenn ja, müssen sie auch entkommen. Meine Antwort ist, zu versuchen, so spät wie möglich (aber nicht später!) Beim Erstellen der SQL-Abfrage zu bereinigen.

In den meisten Fällen ist die Parameterbindung jedoch der richtige Weg - sie ist einfach einfacher.

Pontus Gagge
quelle
2
Sie können die Parametersubstitution auch dann verwenden, wenn Sie Ihre eigenen Abfragen erstellen.
Nick Johnson
1
Sie sollten die SQL-Anweisungszeichenfolge von Grund auf neu erstellen, aber dennoch die Parametersubstitution verwenden.
JeeBee
Nein, erstellen Sie Ihre SQL-Anweisungen NIEMALS von Grund auf neu.
AviD
8

Input-Hygiene ist nicht etwas, das Sie halbherzig machen wollen. Benutze deinen ganzen Arsch. Verwenden Sie reguläre Ausdrücke für Textfelder. Versuchen Sie, Ihre Zahlen auf den richtigen numerischen Typ zu übertragen, und melden Sie einen Validierungsfehler, wenn dies nicht funktioniert. Es ist sehr einfach, in Ihrer Eingabe nach Angriffsmustern zu suchen, z. B. '-. Angenommen, alle Eingaben des Benutzers sind feindlich.

tom.dietrich
quelle
4
Und wenn Sie vermissen , dass ONE Fall auf ONE Eingang, du bist pwnd.
BryanH
4
"Einige Leute denken, wenn sie mit einem Problem konfrontiert werden" Ich weiß, ich werde reguläre Ausdrücke verwenden. "Jetzt haben sie zwei Probleme."
MickeyfAgain_BeforeExitOfSO
1
@mickeyf Ich weiß, dass dies ein weit verbreitetes Gefühl ist, aber ehrlich gesagt sind reguläre Ausdrücke ziemlich großartig, wenn man sie einmal erfasst hat.
Tom.dietrich
@ tom.dietrich Es kommt immer auf die reale Lebenssituation an. F.ex. Die Regexpr-Syntax ist kein Standard, daher würde ich generell davon abraten, Regexpr in Kontexten zu verwenden, in denen verschiedene Systeme integriert sind, um zusammenzuarbeiten. Dies liegt daran, dass verschiedene Regexpr-Engines Regexprs unterschiedlich bewerten. Noch wichtiger ist, dass diese harte Tatsache normalerweise heruntergespielt oder ignoriert wird, was dazu führen kann, dass Entwickler sich nicht um diese Inkompatibilitäten kümmern, bis sie gebissen werden. Es gibt viele solcher Inkompatibilitäten; siehe f.ex. reguläre-Ausdrücke.info / shorthand.html (Suche auf flavorsdieser Seite).
SantiBailors
6

Es ist sowieso eine schlechte Idee, wie Sie zu wissen scheinen.

Was ist mit so etwas wie dem Zitat in einer solchen Zeichenfolge zu entkommen: \ '

Ihr Ersatz würde führen zu: \ ''

Wenn der Backslash dem ersten Anführungszeichen entgeht, hat das zweite Anführungszeichen die Zeichenfolge beendet.

WW.
quelle
3
Danke für die Antwort! Ich weiß, dass ein Angriff für eine mySQL-Datenbank funktionieren würde, aber ich bin mir ziemlich sicher, dass MS SQL Server keinen Backslash als Escape-Zeichen akzeptiert (ich habe es versucht). Bei mehreren Google-Suchanfragen wurden keine anderen Escape-Zeichen gefunden, weshalb ich mich wirklich fragte, warum dies nicht funktionieren würde.
Patrick
6

Einfache Antwort: Es wird manchmal funktionieren, aber nicht immer. Sie möchten die White-List-Validierung für alles verwenden, was Sie tun, aber mir ist klar, dass dies nicht immer möglich ist. Sie sind daher gezwungen, die beste Blacklist zu verwenden. Ebenso möchten Sie parametrisierte gespeicherte Prozesse in allem verwenden , aber dies ist wiederum nicht immer möglich, sodass Sie gezwungen sind, sp_execute mit Parametern zu verwenden.

Es gibt Möglichkeiten, um jede verwendbare Blacklist zu umgehen, die Sie erstellen können (und einige Whitelists auch).

Eine anständige Beschreibung finden Sie hier: http://www.owasp.org/index.php/Top_10_2007-A2

Wenn Sie dies als schnelle Lösung tun müssen, um Zeit zu haben, eine echte zu installieren, tun Sie es. Aber glaube nicht, dass du in Sicherheit bist.

Ungültiges Zeichen
quelle
6

Es gibt zwei Möglichkeiten, dies zu tun, ohne Ausnahmen, um vor SQL-Injektionen sicher zu sein. vorbereitete Anweisungen oder vorprogrammierte gespeicherte Prozeduren.

olle
quelle
4

Wenn Sie parametrisierte Abfragen zur Verfügung haben, sollten Sie diese jederzeit verwenden. Es genügt eine einzige Abfrage, um durch das Netz zu rutschen, und Ihre Datenbank ist gefährdet.

Kev
quelle
4

Ja, das sollte funktionieren, bis jemand SET QUOTED_IDENTIFIER OFF ausführt und ein doppeltes Anführungszeichen für Sie verwendet.

Bearbeiten: Es ist nicht so einfach, dem böswilligen Benutzer nicht zu erlauben, zitierte Bezeichner zu deaktivieren:

Der ODBC-Treiber für SQL Server Native Client und der OLE DB-Anbieter für SQL Server Native Client für SQL Server setzen QUOTED_IDENTIFIER beim Herstellen der Verbindung automatisch auf ON. Dies kann in ODBC-Datenquellen, in ODBC-Verbindungsattributen oder in OLE DB-Verbindungseigenschaften konfiguriert werden.Der Standardwert für SET QUOTED_IDENTIFIER ist OFF für Verbindungen von DB-Library-Anwendungen.

Wenn eine gespeicherte Prozedur erstellt wird, werden die Einstellungen SET QUOTED_IDENTIFIER und SET ANSI_NULLS erfasst und für nachfolgende Aufrufe dieser gespeicherten Prozedur verwendet .

SET QUOTED_IDENTIFIER auch entspricht auch der Einstellung QUOTED_IDENTIFER von ALTER DATABASE.

SET QUOTED_IDENTIFIER wird zur Analysezeit festgelegt . Die Einstellung zur Analysezeit bedeutet, dass die SET-Anweisung, wenn sie im Stapel oder in der gespeicherten Prozedur vorhanden ist, wirksam wird, unabhängig davon, ob die Codeausführung tatsächlich diesen Punkt erreicht. und die SET-Anweisung wird wirksam, bevor Anweisungen ausgeführt werden.

Es gibt viele Möglichkeiten, wie QUOTED_IDENTIFIER ausgeschaltet werden kann, ohne dass Sie es unbedingt wissen. Zugegeben - dies ist nicht der Exploit für rauchende Waffen, den Sie suchen, aber es ist eine ziemlich große Angriffsfläche. Wenn Sie auch doppelten Anführungszeichen entkommen sind, sind wir natürlich wieder da, wo wir angefangen haben. ;)

Mark Brackett
quelle
1
Das könnte funktionieren, aber wie könnten sie diesen Code zur Ausführung bringen, wenn alle Benutzereingaben in einfache Anführungszeichen gesetzt sind? Eine bestimmte Codezeile, die SQL in den obigen Code einfügen könnte, wäre sehr hilfreich. Vielen Dank!
Patrick
4

Ihre Verteidigung würde scheitern, wenn:

  • Die Abfrage erwartet eher eine Zahl als eine Zeichenfolge
  • Es gab keine andere Möglichkeit, ein einzelnes Anführungszeichen darzustellen, einschließlich:
    • eine Escape-Sequenz wie \ 039
    • ein Unicode-Zeichen

(Im letzteren Fall müsste es sich um etwas handeln, das erst nach dem Ersetzen erweitert wurde.)

AJ.
quelle
4

Patrick, fügen Sie einfache Anführungszeichen um ALLE Eingaben hinzu, sogar um numerische Eingaben? Wenn Sie eine numerische Eingabe haben, diese aber nicht in einfache Anführungszeichen setzen, haben Sie eine Belichtung.

Rob Kraft
quelle
1

Was für ein hässlicher Code wäre all diese Bereinigung der Benutzereingaben! Dann der klobige StringBuilder für die SQL-Anweisung. Die vorbereitete Anweisungsmethode führt zu viel saubererem Code, und die Vorteile von SQL Injection sind eine wirklich schöne Ergänzung.

Auch warum das Rad neu erfinden?

JeeBee
quelle
1

Anstatt ein einzelnes Zitat in (wie es aussieht) zwei einfache Anführungszeichen zu ändern, können Sie es einfach in ein Apostroph oder ein Zitat ändern oder ganz entfernen.

In jedem Fall ist es ein bisschen kludge ... besonders wenn Sie legitimerweise Dinge (wie Namen) haben, die einfache Anführungszeichen verwenden können ...

HINWEIS: Bei Ihrer Methode wird außerdem davon ausgegangen, dass sich jeder, der an Ihrer App arbeitet, immer daran erinnert, Eingaben zu bereinigen, bevor sie in die Datenbank gelangen, was wahrscheinlich die meiste Zeit nicht realistisch ist.

Kevin Fairchild
quelle
Abgestimmt, weil die Antwort keine Frage beantwortet. Bei der Frage geht es darum, Zeichenfolgen in SQL zu maskieren. Wenn Sie einer beliebigen Zeichenfolge entkommen (wie es der Fragesteller versucht, um mit nicht bereinigten Daten umzugehen), können Sie problematische Zeichen nicht einfach durch beliebige andere ersetzen. das korrumpiert Daten. (Auch ein einfaches Zitat ist ein Apostroph (zumindest in ASCII).)
Andrewf
-1

Während Sie möglicherweise eine Lösung finden, die für Zeichenfolgen funktioniert, müssen Sie für numerische Prädikate auch sicherstellen, dass sie nur Zahlen übergeben (einfache Überprüfung ist, ob sie als int / double / decimal analysiert werden können?).

Es ist viel zusätzliche Arbeit.

Joseph Daigle
quelle
-2

Es könnte funktionieren, aber es scheint mir ein wenig hokey. Ich würde empfehlen, zu überprüfen, ob jede Zeichenfolge gültig ist, indem Sie sie stattdessen mit einem regulären Ausdruck testen.

rauben
quelle
-3

Ja, Sie können, wenn ...

Nach dem Studium des Themas halte ich eine von Ihnen vorgeschlagene bereinigte Eingabe für sicher, jedoch nur nach folgenden Regeln:

  1. Sie lassen niemals zu, dass Zeichenfolgenwerte, die von Benutzern stammen, zu etwas anderem als Zeichenfolgenliteralen werden (dh geben Sie keine Konfigurationsoption an: "Geben Sie hier zusätzliche SQL-Spaltennamen / Ausdrücke ein:"). Andere Werttypen als Zeichenfolgen (Zahlen, Datumsangaben, ...): Konvertieren Sie sie in ihre nativen Datentypen und stellen Sie für jeden Datentyp eine Routine für das SQL-Literal bereit.

    • Die Validierung von SQL-Anweisungen ist problematisch
  2. Sie verwenden entweder nvarchar/ ncharcolumns (und Präfix-String-Literale mit N) ODER begrenzen Werte, die in varchar/ charcolumn gehen, nur für ASCII-Zeichen (z. B. Ausnahme beim Erstellen einer SQL-Anweisung)

    • Auf diese Weise vermeiden Sie die automatische Apostrophkonvertierung von CHAR (700) nach CHAR (39) (und möglicherweise andere ähnliche Unicode-Hacks).
  3. Sie überprüfen die Wertelänge immer so, dass sie zur tatsächlichen Spaltenlänge passt (Ausnahme auslösen, wenn länger)

    • Es gab einen bekannten Fehler in SQL Server, der es ermöglichte, den beim Abschneiden ausgelösten SQL-Fehler zu umgehen (was zu einem stillen Abschneiden führte).
  4. Sie stellen sicher, dass SET QUOTED_IDENTIFIERdas immer so istON

    • Vorsicht, es wird in der Analysezeit wirksam, dh auch in unzugänglichen Codeabschnitten

Wenn Sie diese 4 Punkte einhalten, sollten Sie sicher sein. Wenn Sie gegen eine dieser Bestimmungen verstoßen, wird eine Möglichkeit zur SQL-Injection geöffnet.

miroxlav
quelle
1
Es ist, als hätten Sie nicht alle anderen Antworten auf diese 8 Jahre alte Frage gelesen , da eine beliebige Anzahl dieser Antworten darauf hinweist, dass seine Methode die Injektion nicht stoppt, wenn der Angreifer einfach Unicode-Zeichen verwendet.
Hogan
@Hogan - Ich habe es getan, aber ich denke, dass meine Frage einen zusätzlichen Wert hat. Ich habe viel Erfahrung und Tests hinter dem, was ich geschrieben habe. Ich weiß, dass die Verwendung von Abfrageparametern besser ist, aber ich verstehe auch die Situation, in der jemand sie aus verschiedenen Gründen vermeiden muss (z. B. die Forderung des Arbeitgebers, den alten Weg beizubehalten). In diesem Fall denke ich, dass meine Antwort sehr umfassend ist und einen höheren Wert hat als die Antworten mit der Aufschrift "Tu das einfach nicht", weil sie den Weg zeigt. Zeigen Sie mir hier andere Antworten, die den gleichen Weg zeigen, und ich werde in Betracht ziehen, meine zu löschen.
Miroxlav
Ok, wenn (nicht wenn) Ihr System kompromittiert wird, kommen Sie bitte zurück und löschen Sie diese Antwort ... oder Sie könnten eine parametrisierte Abfrage verwenden.
Hogan
@Hogan - Ich habe kein Problem damit :) Aber derzeit behaupte ich, dass es keinen bekannten Weg gibt, dies zu umgehen, wenn Sie die 4 Regeln einhalten, die ich gepostet habe. Wenn Sie wirklich glauben, dass es einen Weg gibt, zeigen Sie einfach, wo.
Miroxlav
Schlechter Rat hombre. Jede Interpolation kann besiegt werden.
Shayne