Sollten wir weiterhin QUOTENAME verwenden, um vor Injektionsangriffen zu schützen?

9

Ich habe mir heute eine alte gespeicherte Prozedur angesehen und festgestellt, dass sie quotenamefür die Eingabeparameter verwendet wird. Nachdem ich ein bisschen gegraben hatte, um herauszufinden, was das genau macht, bin ich auf diese Seite gestoßen . Ich verstehe jetzt, was es tut und wie es verwendet wird, aber die Site sagt, dass es als Abschwächung von SQL Injection-Angriffen verwendet wird. Wenn ich mit asp.net Apps entwickelte, die eine Datenbank direkt abfragten, verwendete ich ADO.Net-Parameter, um Benutzereingaben als Literalwert zu übergeben, und machte mir nie wirklich Sorgen, sie in meinen gespeicherten Prozeduren zu schützen.

Ich schreibe jetzt eine gespeicherte Prozedur, die von Anwendungen verwendet wird, die ich nicht schreibe. Daher muss ich versuchen, mich vor Injektionsangriffen auf Prozedurebene zu schützen. quotenameDies ist der beste Weg, dies zu tun, oder gibt es eine neuere / bessere Funktion Methode?

Code, der mich zu diesem Gedankenmuster gebracht hat ( @parm1ist ein Benutzereingabeparameter):

'SELECT project [Project], project_desc [Description], 
        customer [Customer], cpnyid [Company]
FROM PJPROJ (nolock)
where project like ' + quotename(@parm1,'''') + '
Matthew Verstraete
quelle

Antworten:

17

Ja, in diesem Bereich hat sich nicht viel geändert. Sie sollten sie quotenamefür alle SQL Server-Objektnamen verwenden, die in dynamischem SQL verwendet werden (insbesondere, wenn sie extern für Ihren Code bereitgestellt werden). Neben der Reduzierung der SQL-Injektion bedeutet dies auch, dass Ihr Code für nicht standardmäßige Bezeichnernamen ordnungsgemäß funktioniert.

Die Funktion ist jedoch nur für Objektnamen (z. B. Tabellen-, Spalten-, Datenbanknamen) geeignet.

Sie sollten versuchen, alles andere zu parametrisieren und zu verwenden sp_executesql, indem Sie Parameter übergeben, anstatt diese in die Abfragezeichenfolge zu verketten.

Der endgültige Artikel zu diesem Thema ist immer noch Der Fluch und der Segen von Dynamic SQL


Bearbeiten. Jetzt haben Sie den Code angegeben, der den zweiten Parameter 'zum Hinzufügen der äußeren Anführungszeichen und zum Umgehen einzelner Anführungszeichen durch Verdoppeln vor dem Einfügen in die Zeichenfolge übergibt . Dies ist keine gute Verwendung von Quotename. Es schlägt fehl (return null), wenn die Zeichenfolge größer als 128 Zeichen ist.

Darüber hinaus bleiben möglicherweise noch SQL-Injection-Möglichkeiten übrig, wenn die Zeichenfolge U + 02BC anstelle des Standardapostrophs enthält und die Zeichenfolge nach der Bereinigung einem Varchar zugewiesen wird ( wo sie stillschweigend in ein reguläres Apostroph umgewandelt werden kann ).

Der richtige Weg, dies zu tun, besteht darin, die Abfrage parametrisiert zu lassen. Und geben Sie dann den @parm1Wert an an weitersys.sp_executesql

DECLARE @Sql NVARCHAR(MAX);

SET @Sql = '
SELECT project      [Project],
       project_desc [Description],
       customer     [Customer],
       cpnyid       [Company]
FROM   PJPROJ (nolock)
WHERE  project LIKE @parm1 
';

EXEC sys.sp_executesql
  @Sql,
  N'@parm1 varchar(100)',
  @parm1 = 'foobar%'; 
Martin Smith
quelle