Ich habe die folgende gespeicherte Prozedur erstellt:
ALTER PROCEDURE usp_actorBirthdays (@nameString nvarchar(100), @actorgender nvarchar(100))
AS
SELECT ActorDOB, ActorName FROM tblActor
WHERE ActorName LIKE '%' + @nameString + '%'
AND ActorGender = @actorgender
Jetzt habe ich versucht, so etwas zu tun. Vielleicht mache ich das falsch, aber ich möchte sicher sein, dass eine solche Prozedur jede SQL-Injection verhindern kann:
EXEC usp_actorBirthdays 'Tom', 'Male; DROP TABLE tblActor'
Die folgende Abbildung zeigt, dass die oben genannte SQL in SSMS ausgeführt wird und die Ergebnisse anstelle eines Fehlers korrekt angezeigt werden:
Übrigens habe ich diesen Teil nach dem Semikolon hinzugefügt, nachdem die Abfrage ausgeführt wurde. Dann habe ich es erneut ausgeführt, aber als ich überprüft habe, ob die Tabelle tblActor existiert oder nicht, war sie immer noch da. Mache ich etwas falsch? Oder ist das wirklich spritzwassergeschützt? Ich denke, was ich hier zu fragen versuche, ist auch, dass eine gespeicherte Prozedur wie diese sicher ist? Vielen Dank.
EXEC usp_actorBirthdays 'Tom', 'Male''; DROP TABLE tblActor'
Antworten:
Dieser Code funktioniert ordnungsgemäß, weil er:
Damit SQL Injection zu arbeiten, müssen Sie eine Abfrage - String bauen (die Sie nicht tun werden) und nicht übersetzen einzelne Apostrophe (
'
) in entkam-Apostrophe (''
) (die über die Eingangsparameter entkam).Bei dem Versuch, einen "kompromittierten" Wert einzugeben, handelt es sich bei der
'Male; DROP TABLE tblActor'
Zeichenfolge lediglich um eine einfache Zeichenfolge.Nun, wenn Sie etwas in der Art von:
dann , dass wäre anfällig für SQL - Injection , da die Abfrage nicht in dem aktuellen ist, vorab geparsten Kontext; Diese Abfrage ist im Moment nur eine weitere Zeichenfolge. Der Wert von
@InputParam
könnte also'2015-10-31'; SELECT * FROM PlainTextCreditCardInfo;
ein Problem darstellen, da diese Abfrage wie folgt gerendert und ausgeführt wird:Dies ist einer von mehreren Hauptgründen für die Verwendung von Stored Procedures: von Natur aus sicherer (vorausgesetzt, Sie umgehen diese Sicherheit nicht, indem Sie Abfragen wie oben gezeigt erstellen, ohne die Werte der verwendeten Parameter zu validieren). Wenn Sie jedoch dynamisches SQL erstellen müssen, sollten Sie dies auch folgendermaßen parametrisieren
sp_executesql
:Bei Verwendung dieses Ansatzes würde jemand, der versucht,
'2015-10-31'; SELECT * FROM PlainTextCreditCardInfo;
einenDATETIME
Eingabeparameter zu übergeben, beim Ausführen der gespeicherten Prozedur einen Fehler erhalten. Oder selbst wenn die gespeicherte Prozedur@InputParameter
als akzeptiertNVARCHAR(100)
würde, müsste sie in eine konvertiertDATETIME
werden, um in diesensp_executesql
Aufruf überzugehen. Und selbst wenn der Parameter in Dynamic SQL ein Zeichenfolgentyp ist, wird bei der gespeicherten Prozedur in erster Linie jedes einzelne Apostroph automatisch zu einem doppelten Apostroph maskiert.Es gibt eine weniger bekannte Angriffsart, bei der der Angreifer versucht, das Eingabefeld mit Apostrophen auszufüllen, sodass eine Zeichenfolge in der gespeicherten Prozedur, die zum Erstellen von Dynamic SQL verwendet werden würde, jedoch als zu klein deklariert wird, nicht für alles passen kann und schiebt den abschließenden Apostroph heraus und endet irgendwie mit der richtigen Anzahl von Apostrophen, um nicht länger innerhalb der Zeichenkette "entkommen" zu werden. Dies wird als SQL-Kürzung bezeichnet und wurde in einem Artikel des MSDN-Magazins mit dem Titel "Neue SQL-Kürzungsangriffe und ihre Vermeidung" von Bala Neerumalla behandelt. Der Artikel ist jedoch nicht mehr online. Die Ausgabe mit diesem Artikel - die Ausgabe vom November 2006 des MSDN Magazine - ist nur als Windows-Hilfedatei (in .chmFormat). Wenn Sie es herunterladen, wird es möglicherweise aufgrund der Standardsicherheitseinstellungen nicht geöffnet. In diesem Fall klicken Sie mit der rechten Maustaste auf die Datei MSDNMagazineNovember2006en-us.chm und wählen Sie "Eigenschaften". In einer dieser Registerkarten gibt es eine Option für "Vertraue diesem Dateityp" (oder so ähnlich), die überprüft / aktiviert werden muss. Klicken Sie auf die Schaltfläche "OK" und versuchen Sie dann erneut, die CHM- Datei zu öffnen .
Eine weitere Variante des Truncation-Angriffs ist die Annahme, dass eine lokale Variable verwendet wird, um den vom Benutzer angegebenen "sicheren" Wert zu speichern, da einzelne Anführungszeichen so verdoppelt wurden, dass sie ausgeblendet werden, um diese lokale Variable aufzufüllen und das einzelne Anführungszeichen zu platzieren Am Ende. Die Idee dabei ist, dass, wenn die lokale Variable nicht die richtige Größe hat, am Ende nicht genügend Platz für das zweite einfache Anführungszeichen vorhanden ist. Lassen Sie die Variable mit einem einfachen Anführungszeichen enden, das dann mit dem einfachen Anführungszeichen kombiniert wird Beendet den Literalwert in Dynamic SQL und wandelt dieses endende einfache Anführungszeichen in ein eingebettetes einfaches Anführungszeichen mit Escapezeichen um. Das Zeichenfolgenliteral in Dynamic SQL endet dann mit dem nächsten einfachen Anführungszeichen, mit dem das nächste Zeichenfolgenliteral beginnen sollte. Beispielsweise:
Hier ist nun das auszuführende Dynamic SQL:
Dasselbe dynamische SQL in einem besser lesbaren Format lautet:
Dies zu beheben ist einfach. Führen Sie einfach einen der folgenden Schritte aus:
Verwenden Sie keine lokale Variable, um den "festen" Wert zu speichern. stecke das einfach
REPLACE()
direkt in die Erstellung des Dynamic SQL:Das Dynamic SQL ist nicht mehr gefährdet:
Anmerkungen zum obigen Funktionsbeispiel:
DELETE tableName
um destruktiv zu sein, aber weniger wahrscheinlich, um einen Back-Door-Benutzer hinzuzufügen oder ein Administratorkennwort zu ändern.Ausführlichere Informationen zu SQL Injection (in Bezug auf verschiedene RDBMS und Szenarien) finden Sie im Open Web Application Security Project (OWASP) unter:
Testen auf SQL Injection
Verwandte Antwort auf Stapelüberlauf bei SQL Injection und SQL Truncation:
Wie sicher ist T-SQL, nachdem Sie das Escape-Zeichen ersetzt haben?
quelle
Die einfache Sache ist, dass Sie Daten überhaupt nicht mit Befehlen verwechseln. Die Werte für die Parameter werden niemals als Teil des Befehls behandelt und daher niemals ausgeführt.
Ich habe darüber gebloggt unter: http://blogs.lobsterpot.com.au/2015/02/10/sql-injection-the-golden-rule/
quelle