Injection

0

SQL Injection

SQL Injection ist eine Code-Injektionstechnik, die Ihre Datenbank zerstören kann.

SQL Injection ist eine der häufigsten Web-Hacking-Techniken.

Unter SQL Injection versteht man die Platzierung von Schadcode in SQL-Anweisungen über die Eingabe über eine Webseite.

SQL in Webseiten

SQL Injection tritt normalerweise auf, wenn Sie einen Benutzer um Eingaben wie seinen Benutzernamen/seine Benutzer-ID bitten und der Benutzer Ihnen anstelle eines Namens/einer ID eine SQL Anweisung gibt, die Sie unwissentlich in Ihrer Datenbank ausführen.

Sehen Sie sich das folgende Beispiel an, das eine SELECT Anweisung erstellt, indem einer Auswahlzeichenfolge eine Variable (txtUserId) hinzugefügt wird. Die Variable wird aus der Benutzereingabe (getRequestString) abgerufen:

Beispiel

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Der Rest dieses Kapitels beschreibt die potenziellen Gefahren der Verwendung von Benutzereingaben in SQL Anweisungen.

SQL Injection basierend auf 1=1 ist immer wahr

Schauen Sie sich das obige Beispiel noch einmal an. Der ursprüngliche Zweck des Codes bestand darin, eine SQL Anweisung zum Auswählen eines Benutzers mit einer bestimmten Benutzer-ID zu erstellen.

Wenn es nichts gibt, was einen Benutzer daran hindert, „falsche“ Eingaben zu machen, kann der Benutzer eine „intelligente“ Eingabe wie diese machen:

UserId: 

Die SQL Anweisung sieht dann folgendermaßen aus:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

Das obige SQL ist gültig und gibt ALLE Zeilen aus der Tabelle „Benutzer“ zurück, da ODER 1=1 immer WAHR ist.

Sieht das obige Beispiel gefährlich aus? Was ist, wenn die Tabelle „Benutzer“ Namen und Passwörter enthält?

Die obige SQL Anweisung ist im Wesentlichen dieselbe wie diese:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;

Ein Hacker könnte Zugriff auf alle Benutzernamen und Passwörter in einer Datenbank erhalten, indem er einfach 105 ODER 1=1 in das Eingabefeld eingibt.

SQL Injection basierend auf „“=““ ist immer wahr

Hier ist ein Beispiel für eine Benutzeranmeldung auf einer Website:

Benutzername:

Passwort:

Beispiel

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

Ergebnis

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

Ein Hacker könnte Zugriff auf Benutzernamen und Passwörter in einer Datenbank erhalten, indem er einfach “ ODER „“=“ in das Textfeld für den Benutzernamen oder das Passwort einfügt:

Benutzername:

Passwort:

Der Code auf dem Server erstellt eine gültige SQL Anweisung wie diese:

Ergebnis

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

Das obige SQL ist gültig und gibt alle Zeilen aus der Tabelle „Benutzer“ zurück, da ODER „“=“ immer WAHR ist.

SQL Injection basierend auf gebündelten SQL Anweisungen

Die meisten Datenbanken unterstützen die Verarbeitung von SQL Anweisungen im Batch.

Ein Batch von SQL Anweisungen ist eine Gruppe von zwei oder mehr SQL-Anweisungen, die durch Semikolon getrennt sind.

Die folgende SQL Anweisung gibt alle Zeilen aus der Tabelle „Benutzer“ zurück und löscht anschließend die Tabelle „Lieferanten“.

Beispiel

SELECT * FROM Users; DROP TABLE Suppliers

Schauen Sie sich das folgende Beispiel an:

Beispiel

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Und folgende Eingabe:

Benutzer-ID:

Die gültige SQL Anweisung würde folgendermaßen aussehen:

Ergebnis

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;

Verwenden Sie SQL Parameter zum Schutz

Um eine Website vor SQL Injection zu schützen, können Sie SQL-Parameter verwenden.

SQL Parameter sind Werte, die einer SQL-Abfrage zum Ausführungszeitpunkt auf kontrollierte Weise hinzugefügt werden.

ASP.NET Razor-Beispiel

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

Beachten Sie, dass Parameter in der SQL Anweisung durch ein @-Zeichen dargestellt werden.

Die SQL Engine prüft jeden Parameter, um sicherzustellen, dass er für die jeweilige Spalte korrekt ist und wörtlich und nicht als Teil des auszuführenden SQL behandelt wird.

Ein weiteres Beispiel

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);

Beispiele

Die folgenden Beispiele zeigen, wie parametrisierte Abfragen in einigen gängigen Websprachen erstellt werden.

SELECT ANWEISUNG IN ASP.NET:

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();

INSERT INTO ANWEISUNG IN ASP.NET:

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();

INSERT INTO ANWEISUNG IN PHP:

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();
Nach oben scrollen