1. Was ist ein SQL-Injection-Angriff?
Der sogenannte SQL-Injection-Angriff bedeutet, dass der Angreifer SQL-Befehle in das Eingabefeld eines Webformulars oder den Abfragestring einer Seitenanforderung einfügt und den Server dazu verleitet, schädliche SQL-Befehle auszuführen. In einigen Formularen werden Benutzereingaben direkt zum Erstellen (oder Beeinflussen) dynamischer SQL-Befehle oder als Eingabeparameter für gespeicherte Prozeduren verwendet. Solche Formulare sind besonders anfällig für SQL-Injection-Angriffe. Zu den gängigen SQL-Injection-Angriffsprozessen gehören:
⑴ Eine ASP.NET-Webanwendung verfügt über eine Anmeldeseite. Diese Anmeldeseite steuert, ob der Benutzer das Recht hat, auf die Anwendung zuzugreifen.
⑵ Der auf der Anmeldeseite eingegebene Inhalt wird direkt zum Erstellen dynamischer SQL-Befehle oder direkt als Parameter gespeicherter Prozeduren verwendet. Hier ist ein Beispiel für eine ASP.NET-Anwendung, die eine Abfrage erstellt:
System.Text.StringBuilder query = new System.Text.StringBuilder(
„SELECT * from Users WHERE login = '“)
.Append(txtLogin.Text).Append("' AND password='")
.Append(txtPassword.Text).Append("'");
⑶ Der Angreifer gibt in die Eingabefelder für Benutzername und Passwort etwas wie „' oder ‚1‘=‘1“ ein.
⑷ Nachdem der vom Benutzer eingegebene Inhalt an den Server übermittelt wurde, führt der Server den obigen ASP.NET-Code aus, um einen SQL-Befehl zur Abfrage des Benutzers zu erstellen. Da der vom Angreifer eingegebene Inhalt jedoch sehr speziell ist, ist der letzte SQL-Befehl wird zu: SELECT * from Users WHERE login = '' oder '1'='1' AND password = '' oder '1'='1'.
⑸ Der Server führt eine Abfrage oder einen gespeicherten Prozess aus, um die vom Benutzer eingegebenen Identitätsinformationen mit den auf dem Server gespeicherten Identitätsinformationen zu vergleichen.
⑹ Da der SQL-Befehl tatsächlich durch den Injektionsangriff geändert wurde und die Identität des Benutzers nicht wirklich authentifizieren kann, autorisiert das System den Angreifer fälschlicherweise.
Wenn ein Angreifer weiß, dass die Anwendung den im Formular eingegebenen Inhalt direkt für Abfragen zur Identitätsüberprüfung verwenden wird, wird er versuchen, einige spezielle SQL-Zeichenfolgen einzugeben, um die Abfrage zu manipulieren, ihre ursprüngliche Funktionalität zu ändern und das System dazu zu verleiten, Zugriffsberechtigungen zu erteilen.
Abhängig von der Systemumgebung ist auch der Schaden, den ein Angreifer anrichten kann, unterschiedlich und wird hauptsächlich durch die Sicherheitsberechtigungen der Anwendung für den Zugriff auf die Datenbank bestimmt. Wenn das Benutzerkonto über Administrator- oder andere relativ fortgeschrittene Rechte verfügt, kann der Angreifer verschiedene Vorgänge an den Datenbanktabellen ausführen, die er ausführen möchte, darunter das Hinzufügen, Löschen oder Aktualisieren von Daten oder sogar das direkte Löschen der Tabelle.
2. Wie kann man vorbeugen?
Glücklicherweise ist es nicht besonders schwierig, das Eindringen von SQL-Injection-Angriffen in ASP.NET-Anwendungen zu verhindern. Sie müssen lediglich den gesamten Eingabeinhalt filtern, bevor Sie den Formulareingabeinhalt zum Erstellen des SQL-Befehls verwenden. Das Filtern von Eingaben kann auf verschiedene Arten erfolgen.
⑴ In Situationen, in denen SQL-Abfragen dynamisch erstellt werden, können die folgenden Techniken verwendet werden:
Erstens: Ersetzen Sie einfache Anführungszeichen, dh ändern Sie alle einfachen Anführungszeichen in zwei einfache Anführungszeichen, um zu verhindern, dass Angreifer die Bedeutung von SQL-Befehlen ändern. Wenn wir uns das vorherige Beispiel noch einmal ansehen, wird offensichtlich „SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'“ erhalten das gleiche "SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'" unterschiedliche Ergebnisse.
Zweitens: Entfernen Sie alle Bindestriche im Benutzereingabeinhalt, um zu verhindern, dass Angreifer Abfragen wie „SELECT * from Users WHERE login = 'mas' -- AND password =''“ erstellen, da das Suffix solcher Abfragen zur Hälfte kommentiert wurde Der Angreifer muss lediglich einen legalen Benutzer-Anmeldenamen und nicht das Passwort des Benutzers kennen, um erfolgreich Zugriff zu erhalten.
Drittens: Beschränken Sie die Berechtigungen des Datenbankkontos, das zum Ausführen von Abfragen verwendet wird. Verwenden Sie verschiedene Benutzerkonten, um Abfrage-, Einfüge-, Aktualisierungs- und Löschvorgänge durchzuführen. Durch die Isolierung der Vorgänge, die von verschiedenen Konten ausgeführt werden können, wird verhindert, dass der ursprünglich für die Ausführung des SELECT-Befehls verwendete Ort für die Ausführung des INSERT-, UPDATE- oder DELETE-Befehls verwendet wird.
⑵ Verwenden Sie gespeicherte Prozeduren, um alle Abfragen auszuführen. Die Art und Weise, wie SQL-Parameter übergeben werden, verhindert, dass Angreifer für Angriffe einfache Anführungszeichen und Bindestriche verwenden. Darüber hinaus können Datenbankberechtigungen so eingeschränkt werden, dass nur die Ausführung bestimmter gespeicherter Prozeduren möglich ist. Alle Benutzereingaben müssen dem Sicherheitskontext der aufgerufenen gespeicherten Prozedur entsprechen, sodass Injektionsangriffe nur schwer möglich sind.
⑶ Begrenzen Sie die Länge der Formular- oder Abfragezeichenfolgeneingabe. Wenn der Anmeldename des Benutzers nur maximal 10 Zeichen umfasst, dürfen nicht mehr als 10 Zeichen in das Formular eingegeben werden. Dies erhöht die Schwierigkeit für Angreifer erheblich, schädlichen Code in SQL-Befehle einzufügen.
⑷ Überprüfen Sie die Rechtmäßigkeit der Benutzereingaben und stellen Sie sicher, dass der Eingabeinhalt nur legale Daten enthält. Die Datenprüfung sollte sowohl auf der Client- als auch auf der Serverseite durchgeführt werden. Die serverseitige Validierung wird durchgeführt, um die fragile Sicherheit des clientseitigen Validierungsmechanismus auszugleichen.
Auf der Clientseite ist es für einen Angreifer durchaus möglich, an den Quellcode der Webseite zu gelangen, das Skript zur Überprüfung der Rechtmäßigkeit zu ändern (oder das Skript direkt zu löschen) und dann den illegalen Inhalt über das geänderte Formular an den Server zu übermitteln. Daher besteht die einzige Möglichkeit, sicherzustellen, dass der Verifizierungsvorgang tatsächlich durchgeführt wurde, darin, die Verifizierung auch auf der Serverseite durchzuführen. Sie können viele der integrierten Validierungsobjekte verwenden, z. B. RegularExpressionValidator, der automatisch clientseitige Skripts zur Validierung generieren kann, und natürlich können Sie auch serverseitige Methodenaufrufe einfügen. Wenn Sie kein vorgefertigtes Validierungsobjekt finden, können Sie über CustomValidator selbst eines erstellen.
⑸ Verschlüsseln und speichern Sie den Anmeldenamen, das Passwort und andere Daten des Benutzers. Das Verschlüsseln der vom Benutzer eingegebenen Daten und der anschließende Vergleich mit den in der Datenbank gespeicherten Daten ist gleichbedeutend mit dem „Sterilisieren“ der vom Benutzer eingegebenen Daten. Die vom Benutzer eingegebenen Daten haben für die Datenbank keine besondere Bedeutung mehr Angreifer daran gehindert, SQL-Befehle einzuschleusen. Die System.Web.Security.FormsAuthentication-Klasse verfügt über eine HashPasswordForStoringInConfigFile, die sich sehr gut zum Bereinigen von Eingabedaten eignet.
⑹ Überprüfen Sie die Anzahl der Datensätze, die von der Abfrage zurückgegeben wurden, die die Daten extrahiert hat. Wenn das Programm nur die Rückgabe eines Datensatzes erfordert, der tatsächlich zurückgegebene Datensatz jedoch mehr als eine Zeile umfasst, wird dies als Fehler behandelt.