Dieser Artikel wurde maschinell übersetzt. Wenn Sie die englische Version des Artikels anzeigen möchten, aktivieren Sie das Kontrollkästchen Englisch. Sie können den englischen Text auch in einem Popupfenster anzeigen, indem Sie den Mauszeiger über den Text bewegen.
Übersetzung
Englisch
Diese Dokumentation wurde archiviert und wird nicht länger gepflegt.

CA2100: SQL-Abfragen auf Sicherheitsrisiken überprüfen

TypeName

ReviewSqlQueriesForSecurityVulnerabilities

CheckId

CA2100

Kategorie

Microsoft.Security

Unterbrechende Änderung

Nicht unterbrechend

Eine Methode legt die IDbCommand.CommandText-Eigenschaft mithilfe einer Zeichenfolge fest, die aus einem Zeichenfolgenargument für die Methode erstellt wird.

Diese Regel setzt voraus, dass das Zeichenfolgenargument Benutzereingaben enthält. Eine aus Benutzereingaben erstellte SQL-Befehlszeichenfolge ist anfällig für SQL-Injection-Angriffe. Bei einem SQL-Injection-Angriff stellt ein böswilliger Benutzer Eingaben bereit, die das Design der Abfrage so ändern, dass die zugrunde liegende Datenbank beschädigt wird oder der Benutzer unbefugten Zugriff auf die zugrunde liegende Datenbank erhält. Zu den typischen Techniken zählen das Einfügen eines einfachen Anführungszeichens oder eines Apostrophs, das als Trennzeichen für ein SQL-Zeichenfolgenliteral interpretiert wird, das Einfügen von zwei Bindestrichen, die einen SQL-Kommentar kennzeichnen, sowie das Einfügen eines Semikolons, wodurch angezeigt wird, dass ein neuer Befehl folgt. Falls die Benutzereingaben Teil der Abfrage sein müssen, sollten Sie eine der im Folgenden nach ihrer Effektivität aufgelisteten Methoden anwenden, um das Risiko eines Angriffs zu verringern.

  • Verwenden Sie eine gespeicherte Prozedur.

  • Verwenden Sie eine parametrisierte Befehlszeichenfolge.

  • Überprüfen Sie die Benutzereingaben vor dem Erstellen der Befehlszeichenfolge sowohl auf Typ als auch auf Inhalt.

Die folgenden .NET Framework-Typen implementieren die CommandText-Eigenschaft oder bieten Konstruktoren, die die Eigenschaften mithilfe eines Zeichenfolgenarguments festlegen.

Beachten Sie, dass diese Regel verletzt wird, wenn die ToString-Methode eines Typs explizit oder implizit zum Erstellen der Abfragezeichenfolge verwendet wird. Im Folgenden finden Sie ein Beispiel.

int x = 10;
string query = "SELECT TOP " + x.ToString() + " FROM Table";

Die Regel wird verletzt, da ein böswilliger Benutzer die ToString()-Methode überschreiben kann.

Die Regel wird auch verletzt, wenn ToString implizit verwendet wird.

int x = 10;
string query = String.Format("SELECT TOP {0} FROM Table", x);

Um einen Verstoß gegen diese Regel zu korrigieren, verwenden Sie eine parametrisierte Abfrage.

Eine Warnung dieser Regel kann gefahrlos unterdrückt werden, wenn der Befehlstext keine Benutzereingaben enthält.

Im folgenden Beispiel wird eine Methode, UnsafeQuery, gezeigt, die gegen die Regel verstößt. Außerdem wird eine Methode, SaferQuery gezeigt, die die Regel mithilfe einer parametrisierten Befehlszeichenfolge einhält.


using System;
using System.Data;
using System.Data.SqlClient;

namespace SecurityLibrary
{
   public class SqlQueries
   {
      public object UnsafeQuery(
         string connection, string name, string password)
      {
         SqlConnection someConnection = new SqlConnection(connection);
         SqlCommand someCommand = new SqlCommand();
         someCommand.Connection = someConnection;

         someCommand.CommandText = "SELECT AccountNumber FROM Users " +
            "WHERE Username='" + name + 
            "' AND Password='" + password + "'";

         someConnection.Open();
         object accountNumber = someCommand.ExecuteScalar();
         someConnection.Close();
         return accountNumber;
      }

      public object SaferQuery(
         string connection, string name, string password)
      {
         SqlConnection someConnection = new SqlConnection(connection);
         SqlCommand someCommand = new SqlCommand();
         someCommand.Connection = someConnection;

         someCommand.Parameters.Add(
            "@username", SqlDbType.NChar).Value = name;
         someCommand.Parameters.Add(
            "@password", SqlDbType.NChar).Value = password;
         someCommand.CommandText = "SELECT AccountNumber FROM Users " + 
            "WHERE Username=@username AND Password=@password";

         someConnection.Open();
         object accountNumber = someCommand.ExecuteScalar();
         someConnection.Close();
         return accountNumber;
      }
   }

   class MalaciousCode
   {
      static void Main(string[] args)
      {
         SqlQueries queries = new SqlQueries();
         queries.UnsafeQuery(args[0], "' OR 1=1 --", "anything");
         // Resultant query (which is always true): 
         // SELECT AccountNumber FROM Users WHERE Username='' OR 1=1

         queries.SaferQuery(args[0], "' OR 1 = 1 --", "anything");
         // Resultant query (notice the additional single quote character):
         // SELECT AccountNumber FROM Users WHERE Username=''' OR 1=1 --'
         //                                   AND Password='anything'
      }
   }
}


Anzeigen: