Frage

Ich habe beide meine Kollegen gepredigt und hier auf SO über die Güte von Parametern in SQL-Abfragen verwendet, vor allem in .NET-Anwendungen. Ich habe sogar so weit, zu versprechen, sie als gäbe Immunität gegen SQL-Injection-Angriffe gegangen.

Aber ich fange an zu fragen, ob das wirklich wahr ist. Gibt es bekannte SQL-Injection-Angriffe, die erfolgreich gegen eine parametrisierte Abfrage wird? Können Sie zum Beispiel eine Zeichenfolge senden, die einen Pufferüberlauf auf dem Server verursacht?

Es gibt natürlich auch andere Überlegungen, um sicherzustellen, dass eine Web-Anwendung sicher ist (wie Eingang Benutzer Hygienisierung und all das Zeugs), aber jetzt habe ich von SQL-Injections denke. Ich bin besonders interessiert an Angriffen gegen MsSQL 2005 und 2008, da sie meine primären Datenbanken sind, aber alle Datenbanken sind interessant.

Edit: Um zu klären, was ich von Parametern und parametrisierte Abfragen bedeuten. Durch Parametern meine ich mit „Variablen“ statt Aufbau der SQL-Abfrage in einer Zeichenkette.
Anstatt also, dies zu tun:

SELECT * FROM Table WHERE Name = 'a name'

Wir tun dies:

SELECT * FROM Table WHERE Name = @Name

und setzen Sie den Wert des @Name Parameter auf der Abfrage / Befehlsobjekt.

War es hilfreich?

Lösung

Platzhalter ist genug, um Injektionen zu verhindern. Sie könnten noch offen seinen Buffer Overflows, aber das ist ein ganz anderes Aroma des Angriffs aus einer SQL-Injektion (der Angriffsvektor nicht SQL-Syntax wäre aber binär). Da die übergebenen Parameter werden alle richtig übersetzt werden, gibt es keine Möglichkeit für einen Angreifer Daten zu übergeben, die wie „live“ SQL behandelt werden.

Sie können keine Funktionen innerhalb Platzhalter verwenden, und Sie können keine Platzhalter als Spalte oder Tabellennamen verwenden, da sie als Stringliterale sind entkommen und zitiert.

Wenn Sie jedoch Parameter als Teil einer String-Verkettung in Ihrer dynamischen Abfrage, Sie sind immer noch anfällig für Injektion, weil die Saiten nicht entgangen sein, sondern sein wörtlich zu nehmen. Die Verwendung anderer Typen für Parameter (wie integer) ist sicher.

Das heißt, wenn Sie die Verwendung Eingang verwenden den Wert von etwas wie security_level zu setzen, dann könnte jemand einfach selbst Administratoren in Ihrem System vornehmen und haben ein frei für alles Mögliche. Aber das ist nur grundlegende Eingabevalidierung und hat nichts mit SQL-Injection zu tun.

Andere Tipps

Nein, es gibt immer noch Gefahr von SQL-Injection, immer wenn Sie nicht validierten Daten in eine SQL-Abfrage einfügen.

Abfrageparameter helfen, dieses Risiko zu vermeiden, indem wörtliche Werte aus der SQL-Syntax zu trennen.

'SELECT * FROM mytable WHERE colname = ?'

Das ist in Ordnung, aber es gibt andere Zwecke von Daten in eine dynamische SQL-Abfrage interpoliert, die nicht Abfrageparameter verwenden kann, weil es nicht ein SQL-Wert ist, sondern ein Tabellenname, Spaltenname, Ausdruck oder eine andere Syntax.

'SELECT * FROM ' + @tablename + ' WHERE colname IN (' + @comma_list + ')'
' ORDER BY ' + @colname'

Dabei spielt es keine Rolle, ob Sie gespeicherte Prozeduren verwenden oder Ausführen von dynamischen SQL-Abfragen direkt von Anwendungscode. Das Risiko ist immer noch da.

Das Mittel ist in diesen Fällen zu beschäftigen FIEO bei Bedarf:

  • Filter Input:. bestätigen, dass die Daten aussehen legitime ganzen Zahlen, Tabellennamen, Spaltennamen, etc., bevor Sie sie einschalten

  • Escape Output: in diesem Fall "Ausgang": Daten in eine SQL-Abfrage setzen. Wir verwenden Funktionen Variablen als Stringliterale in einem SQL-Ausdruck, zu transformieren, so dass die Anführungszeichen und andere Sonderzeichen innerhalb der Zeichenfolge entkommen sind. Wir sollten auch Funktionen verwenden, um Variablen transformieren, die als Tabellennamen verwendet werden würden, Spaltennamen usw. Wie für andere Syntax, wie das Schreiben ganzen SQL-Ausdrücke dynamisch, das ist ein komplexeres Problem.

Es scheint eine gewisse Verwirrung in diesem Thread über die Definition einer „parametrisiert Abfrage“ zu sein.

  • SQL wie eine gespeicherte Prozedur, die Parameter akzeptiert.
  • SQL, die das DBMS Auflistung Parameter aufgerufen wird.

die frühere Definition gegeben, viele der Links vom Arbeits Angriffen.

Aber die „normale“ Definition ist die letztere. Da die Definition, weiß ich nicht, jede SQL-Injection-Attacke, die funktionieren wird. Das bedeutet nicht, dass es nicht nur einen, aber ich habe noch zu sehen.

Aus den Kommentaren, ich drücke mich nicht klar genug, so dass hier ein Beispiel, das hoffentlich klarer sein wird:

Dieser Ansatz ist offen für SQL-Injection

exec dbo.MyStoredProc 'DodgyText'

Dieser Ansatz nicht offen für SQL-Injection

using (SqlCommand cmd = new SqlCommand("dbo.MyStoredProc", testConnection))
{
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter newParam = new SqlParameter(paramName, SqlDbType.Varchar);
    newParam.Value = "DodgyText";
    .....
    cmd.Parameters.Add(newParam);
    .....
    cmd.ExecuteNonQuery();
}

jeder SQL-Parameter-String-Typ (VARCHAR nvarchar, usw.), die verwendet wird, eine dynamische Abfrage zu konstruieren, ist immer noch anfällig

sonst die Parametertyp-Konvertierung (z.B. in int, dezimal, Datum, etc.) jeglichen Versuch beseitigen sollte einzuspritzen sql über den Parameter

EDIT: ein Beispiel, in dem Parameter @ p1 sollte ein Tabellenname sein

create procedure dbo.uspBeAfraidBeVeryAfraid ( @p1 varchar(64) ) 
AS
    SET NOCOUNT ON
    declare @sql varchar(512)
    set @sql = 'select * from ' + @p1
    exec(@sql)
GO

Wenn @ p1 aus einer Dropdown-Liste ausgewählt es ein potenzieller SQL-Injection-Angriff Vektor ist;

Wenn @ p1 formuliert programmatisch w / out die Fähigkeit des Benutzers dann eingreifen es kein potenzieller Vektor SQL-Injection-Angriff ist

Ein Pufferüberlauf ist nicht SQL-Injection.

Parametrisierte Abfragen garantieren Ihnen sicher vor SQL-Injection sind. Sie haben nicht garantieren, dass es nicht möglich Exploits in Form von Bugs in Ihrem SQL-Server, aber nichts wird, dass gewährleisten.

Ihre Daten sind nicht sicher, wenn Sie dynamische SQL in irgendeiner Weise oder Form verwenden, da die Berechtigungen auf Tabellenebene sein muss. Ja Sie die Art und Menge der Einspritzung Angriff von dieser bestimmten Abfrage beschränkt haben, sondern erhalten den Zugang kann ein Benutzer nicht darauf beschränkt, wenn er oder sie einen Weg in das System findet und Sie sind vollständig vunerable internen Benutzern den Zugriff auf was sie sollten nicht in um Betrug zu begehen oder persönliche Daten zu stehlen zu verkaufen. Dynamische SQL jeglicher Art ist eine gefährliche Praxis. Wenn Sie nicht-dynamische gespeicherte Prozeduren verwenden, können Sie Berechtigungen auf procesdure Ebene gesetzt und kein Benutzer kann alles außer dem tun, was von dem Procs definiert ist (mit Ausnahme von Systemadministratoren natürlich).

Es ist möglich, dass eine gespeicherte Prozedur auf spezielle Typen von SQL-Injektion über Überlauf / Verkürzungs finden, verletzlich zu sein: Injection Aktiviert durch Datenkürzungs hier:

http://msdn.microsoft.com/en-us/library /ms161953.aspx

Denken Sie daran, dass mit Parametern Sie bequem die Zeichenfolge speichern, oder Benutzernamen sagen, wenn Sie keine Politik haben, „); Tabelle Benutzer fallen; -“

Das ist an sich keinerlei Schaden anrichten, aber Sie besser wissen, wo und wie das Datum weiter in Ihrer Anwendung auf verwendet wird (zum Beispiel in einem Cookie gespeichert, später abgerufen andere Sachen zu tun.

Sie können dynamischen SQL als Beispiel ausführen

DECLARE @SQL NVARCHAR(4000);
DECLARE @ParameterDefinition NVARCHAR(4000);

SELECT  @ParameterDefinition = '@date varchar(10)'

SET @SQL='Select CAST(@date AS DATETIME) Date'

EXEC sp_executeSQL @SQL,@ParameterDefinition,@date='04/15/2011'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top