In diesem wikiHow zeigen wir dir, wie du die SQL-Injection mit Prepared Statements in PHP verhinderst. SQL-Injection ist heute eine der häufigsten Sicherheitslücken in Webanwendungen. Vorbereitete Anweisungen verwenden gebundene Parameter und kombinieren keine Variablen mit SQL-Strings, was es einem Angreifer unmöglich macht, die SQL-Anweisung zu ändern.
Vorbereitete Anweisungen kombinieren die Variable mit der kompilierten SQL-Anweisung, sodass die SQL und die Variablen separat gesendet werden. Die Variablen werden dann als reine Strings interpretiert und nicht als Teil der SQL-Anweisung. Wenn Sie die Methoden in den folgenden Schritten verwenden, müssen Sie keine anderen SQL-Injection-Filtertechniken wie mysql_real_escape_string() verwenden.
Schritte
Teil 1 von 2: SQL-Injection verstehen
Schritt 1. SQL Injection ist eine Art von Sicherheitslücke in Anwendungen, die eine SQL-Datenbank verwenden
Die Schwachstelle entsteht, wenn eine Benutzereingabe in einem SQL-Statement verwendet wird:
$name = $_GET['Benutzername']; $query = "SELECT password FROM tbl_user WHERE name = '$name'";
Schritt 2. Der Wert, den ein Benutzer in die URL-Variable username eingibt, wird der Variablen $name zugewiesen
Es wird dann direkt in die SQL-Anweisung eingefügt, sodass der Benutzer die SQL-Anweisung bearbeiten kann.
$name = "admin' ODER 1=1 -- "; $query = "SELECT password FROM tbl_user WHERE name = '$name'";
Schritt 3. Die SQL-Datenbank erhält dann die SQL-Anweisung wie folgt:
SELECT password FROM tbl_users WHERE name = 'admin' ODER 1=1 -- '
-
Dies ist gültiges SQL, aber anstatt ein Passwort für den Benutzer zurückzugeben, gibt die Anweisung alle Passwörter in der Tabelle tbl_user zurück. Dies ist in Ihren Webanwendungen nicht erwünscht.
Teil 2 von 2: Verwenden von mySQLi zum Erstellen von vorbereiteten Anweisungen
Schritt 1. Erstellen Sie die mySQLi SELECT-Abfrage
Verwenden Sie den folgenden Code, um Daten aus einer Tabelle mit mySQLi Prepared Statements AUSWÄHLEN.
$name = $_GET['Benutzername']; if ($stmt = $mysqli->prepare("SELECT password FROM tbl_users WHERE name=?")) { // Eine Variable als String an den Parameter binden. $stmt->bind_param("s", $name); // Anweisung ausführen. $stmt->execute(); // Holen Sie sich die Variablen aus der Abfrage. $stmt->bind_result($pass); // Hole die Daten. $stmt->fetch(); // Daten anzeigen. printf("Passwort für Benutzer %s ist %s\n", $name, $pass); // Schließen Sie die vorbereitete Anweisung. $stmt->close(); }
Hinweis: Die Variable $mysqli ist das mySQLi-Verbindungsobjekt
Schritt 2. Erstellen Sie die mySQLi INSERT-Abfrage
Verwenden Sie den folgenden Code, um Daten mithilfe von vorbereiteten mySQLi-Anweisungen in eine Tabelle einzufügen.
$name = $_GET['Benutzername']; $password = $_GET['password']; if ($stmt = $mysqli->prepare("INSERT INTO tbl_users (name, password) VALUES (?, ?)")) { // Binden Sie die Variablen als Strings an den Parameter. $stmt->bind_param("ss", $name, $password); // Anweisung ausführen. $stmt->execute(); // Schließen Sie die vorbereitete Anweisung. $stmt->close(); }
Hinweis: Die Variable $mysqli ist das mySQLi-Verbindungsobjekt
Schritt 3. Erstellen Sie die mySQLi UPDATE-Abfrage
Verwenden Sie den folgenden Code, um Daten in einer Tabelle mit mySQLi Prepared Statements zu AKTUALISIEREN.
$name = $_GET['Benutzername']; $password = $_GET['password']; if ($stmt = $mysqli->prepare("UPDATE tbl_users SET password = ? WHERE name = ?")) { // Binden Sie die Variablen als Strings an den Parameter. $stmt->bind_param("ss", $password, $name); // Anweisung ausführen. $stmt->execute(); // Schließen Sie die vorbereitete Anweisung. $stmt->close(); }
Hinweis: Die Variable $mysqli ist das mySQLi-Verbindungsobjekt
Schritt 4. Erstellen Sie die mySQLi DELETE-Abfrage
Das folgende Skript zeigt, wie Sie Daten aus einer Tabelle mit mySQLi Prepared Statements löschen.
$name = $_GET['Benutzername']; $password = $_GET['password']; if ($stmt = $mysqli->prepare("DELETE FROM tbl_users WHERE name = ?")) { // Variable als String an den Parameter binden. $stmt->bind_param("s", $name); // Anweisung ausführen. $stmt->execute(); // Schließen Sie die vorbereitete Anweisung. $stmt->close(); }