webentwicklung-frage-antwort-db.com.de

So entgehen Sie einfachen SQL-Abfragen in C # für SqlServer

Ich verwende eine API, die eine SQL-Zeichenfolge erwartet. Ich nehme eine Benutzereingabe, entkomme sie und gebe sie an die API weiter. Die Benutzereingabe ist ziemlich einfach. Es fragt nach Spaltenwerten. So wie:

string name = userInput.Value;

Dann konstruiere ich eine SQL-Abfrage:

string sql = string.Format("SELECT * FROM SOME_TABLE WHERE Name = '{0}'",
                           name.replace("'", "''"));

Ist das sicher genug? Wenn dies nicht der Fall ist, gibt es eine einfache Bibliotheksfunktion, die Spaltenwerte sicher macht:

string sql = string.Format("SELECT * FROM SOME_TABLE WHERE Name = '{0}'",
                           SqlSafeColumnValue(name));

Die API verwendet SQLServer als Datenbank. 

67
sc45

Da die Verwendung von SqlParameter keine Option ist, ersetzen Sie einfach 'with' '(das sind zwei einfache Anführungszeichen, nicht ein Anführungszeichen) in den String-Literalen. Das ist es.

Zu möglichen Downvotern: Lesen Sie die erste Zeile der Frage erneut. "Parameter verwenden" war auch meine Bauchreaktion.

BEARBEITEN: ja, ich kenne SQL-Injection-Angriffe. Wenn Sie der Meinung sind, dass dieses Zitat anfällig für diese ist, geben Sie bitte ein funktionierendes Gegenbeispiel an. Ich denke es ist nicht so.

108
Seva Alekseyev

Es ist am besten, SQL-Parameter zu verwenden, aber es gibt Einschränkungen für 2300 Parameter für die Abfrage. In den meisten Fällen ist dies mehr als genug. Aber in seltenen Fällen, wenn Sie diese Grenze überschreiten, sehe ich dies als Option.

0
charino

Es kann wünschenswert sein, 'mit' 'zu ersetzen, anstatt zu parametrieren, wenn das Problem in einer großen Menge Ad-hoc-SQL in kurzer Zeit gelöst werden muss, mit minimalem Bruchrisiko und minimalem Test.

0
Alex

SqlCommand und Entity Framework verwenden exec sp_executesql...

Es gibt also wirklich eine Alternative zu rohen Saiten, die vermutlich mit Ihrem eigenen Fluchtmuster versehen sind. Mit SqlCommand verwenden Sie technisch parametrisierte Abfragen, umgehen jedoch die ADO.Net-Abstraktion des zugrunde liegenden SQL-Codes. 

Obwohl Ihr Code die SQL-Injektion nicht verhindert, lautet die ultimative Antwort "sp_executesql" und nicht "SqlCommand". 

Ich bin mir jedoch sicher, dass spezielle Anforderungen für die Generierung einer SQL Injection-sicheren Zeichenfolge bestehen, die sp_executesql verwendet.

siehe: Wie gibt man Werte aus einer dynamischen gespeicherten SQL-Prozedur an das Entity Framework zurück?

0
Todd

Ich benutzte für die Suchfunktion dynamisches SQL (ich kann hören, wie das Erschießungskommando ihre Gewehre lädt), aber es brach jedes Mal, wenn ein Benutzer jemanden mit einem Nachnamen wie "O'Reilly" suchte. 

Es ist mir gelungen, eine Umgehung zu finden (lesen Sie "Hack"):

Es wurde eine skalare Funktion in SQL erstellt, die ein einfaches Anführungszeichen durch zwei einfache Anführungszeichen ersetzte
"... Nachname LIKE '% O'Reilly%' AND ..." Wird zu "... Nachname LIKE '% O''Reilly%' UND ..."

Diese Funktion wird von SQL aus aufgerufen, wenn ich vermute, dass Felder ein einfaches Anführungszeichen enthalten könnten, dh Vorname, Nachname.

CREATE FUNCTION [dbo].[fnEscapeSingleQuote]
    (@StringToCheck NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
AS
BEGIN
    DECLARE @Result NVARCHAR(MAX)
    SELECT @Result = REPLACE(@StringToCheck, CHAR(39), CHAR(39) + CHAR(39))
    RETURN @Result
END

Nicht sehr elegant oder effizient, aber es funktioniert, wenn Sie sich im Notfall befinden.

0
ThurstonFord