Neueste Web-Entwicklung Tutorials
 

SQL Injektion


Eine SQL-Injection können Ihre Datenbank zu zerstören.


SQL in Web-Seiten

In den vorangegangenen Kapiteln haben Sie gelernt (und Aktualisierung) Datenbank zum Abrufen von Daten unter Verwendung von SQL.

Wenn SQL verwendet wird, um Daten auf einer Webseite angezeigt werden, ist es üblich, Web-Nutzer geben ihre eigenen Suchwerte zu lassen.

Da SQL-Anweisungen nur Text sind, ist es mit einem kleinen Stück von Computer-Code, leicht, dynamisch SQL-Anweisungen ändern, um die Benutzer mit ausgewählten Daten zur Verfügung zu stellen:

Server-Code

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

Das obige Beispiel erzeugt eine select-Anweisung durch eine Variable (txtUserId) auf eine ausgewählte Zeichenfolge hinzufügen. Die Variable abgerufen wird vom Benutzereingabe (Request) an die Seite.

Der Rest dieses Kapitels beschreibt die möglichen Gefahren von Benutzereingaben in SQL-Anweisungen.


SQL-Injektion

SQL-Injection ist eine Technik, wo böswillige Benutzer injizieren können SQL-Befehle in einer SQL-Anweisung, über Web-Seite-Eingang.

Eingespritzte SQL-Befehle können SQL-Anweisung und gefährden die Sicherheit einer Web-Anwendung ändern.


SQL Injection Basierend auf 1 = 1 ist immer wahr

Schauen Sie sich das Beispiel oben, ein weiteres Mal.

Nehmen wir an, dass der ursprüngliche Zweck des Codes eine SQL-Anweisung zu erstellen war ein Benutzer mit einer bestimmten Benutzer-ID zu wählen.

Wenn es nichts gibt , einen Benutzer von der Eingabe zu verhindern "wrong" Eingang kann der Benutzer etwas eingeben "smart" Eingabe wie folgt aus :

Benutzeridentifikation:

Server Ergebnis

SELECT * FROM Users WHERE UserId = 105 or 1=1

Die SQL-oben ist gültig. Es werden alle Zeilen aus der Tabelle Benutzer zurückgeben, da WHERE 1 = 1 immer wahr ist.

Hat das Beispiel scheinen über gefährlich? Was, wenn der Benutzer Tabellennamen und Passwörter enthält?

Die SQL-Anweisung oben ist sehr ähnlich wie folgt aus:

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

Ein Smart-Hacker könnte durch einfaches Einsetzen 105 oder 1 = 1 in das Eingabefeld den Zugriff auf alle Benutzernamen und Passwörter in einer Datenbank erhalten.


SQL Injection Basierend auf ""="" ist immer wahr

Hier ist eine gemeinsame Konstruktion verwendet, um Benutzer-Login auf einer Website zu überprüfen:

Benutzername:

Passwort:

Server-Code

uName = getRequestString("UserName");
uPass = getRequestString("UserPass");

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

Ein Smart - Hacker könnte durch einfaches Einfügen "oder den Zugriff auf Benutzernamen und Passwörter in einer Datenbank zu bekommen ""=" in der Benutzername oder das Passwort Textfeld ein .

Der Code auf dem Server wird eine gültige SQL-Anweisung wie folgt zu erstellen:

Ergebnis

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

Das Ergebnis SQL gültig ist. Es werden alle Zeilen aus der Tabelle Benutzer zurückgeben, da WHERE "" = "" immer wahr ist.


SQL Injection Basierend auf Batched SQL-Anweisungen

Die meisten Datenbanken unterstützen batched SQL-Anweisung durch ein Semikolon getrennt.

Beispiel

SELECT * FROM Users; DROP TABLE Suppliers

Die SQL oben kehren alle Zeilen in der Tabelle Benutzer, und löschen Sie die Tabelle mit dem Namen Lieferanten.

Wenn wir den folgenden Server-Code hatte:

Server-Code

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

Und die folgende Eingabe:

Benutzeridentifikation:

Der Code auf dem Server würde eine gültige SQL-Anweisung wie folgt zu erstellen:

Ergebnis

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

Parameter für den Schutz

Einige Web - Entwickler verwenden , um eine "blacklist" von Wörtern oder Zeichen in SQL - Eingabe zu suchen, SQL - Injection - Angriffe zu verhindern.

Dies ist keine sehr gute Idee. Viele dieser Wörter (wie zu löschen oder zu fallen) und Zeichen (wie Semikolons und Anführungszeichen) werden in gemeinsame Sprache verwendet, und sollte in vielen Arten von Eingangs zugelassen werden.

(In der Tat sollte es vollkommen legal sein zur Eingabe einer SQL-Anweisung in einem Datenbankfeld.)

Die einzige bewährte Methode, eine Website von SQL-Injection-Angriffe zu schützen, ist SQL-Parameter zu verwenden.

SQL Parameter sind Werte, die eine SQL-Abfrage zur Ausführungszeit hinzugefügt werden, in einer kontrollierten Weise.

ASP.NET Razor Beispiel

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

Beachten Sie, dass Parameter von einem @ Marker in der SQL-Anweisung dargestellt werden.

Die SQL-Engine prüft jeden Parameter, um sicherzustellen, dass es für seine Spalte korrekt ist, und buchstäblich behandelt und nicht als Teil der SQL ausgeführt werden.

Ein anderes 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);

Sie haben gerade gelernt, SQL-Injection zu vermeiden. Eines der Top-Website-Schwachstellen.


Beispiele

Die folgenden Beispiele zeigt, wie parametrisierte Abfragen in einigen gemeinsamen Web-Sprachen zu bauen.

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();