Verhindern Sie SQL Injection in PHP

Subodh Poudel 22 Juni 2021
  1. Verwenden Sie die vorbereiteten Anweisungen und das PDO, um SQL Injection in PHP zu verhindern
  2. Verwenden Sie die Anweisungen Prepared mit der parametrisierten Abfrage, um die SQL-Injection in PHP zu verhindern
  3. Setzen Sie das Attribut PDO::ATTR_EMULATE_PREPARES auf false, um die SQL-Injection zu verhindern
Verhindern Sie SQL Injection in PHP

Wir werden eine Methode einführen, um die SQL-Injection in PHP mithilfe der vorbereiteten Anweisungen und PHP Data Objects (PDO) zu verhindern. Wir verwenden PDO, um die Datenbankkommunikation bei dieser Methode herzustellen. Diese Methode sendet die Daten und Abfragen separat an den Datenbankserver, wodurch das Vermischen von Daten und Server verhindert wird.

Wir werden eine Methode einführen, um die SQL-Injection in PHP mithilfe der vorbereiteten Anweisungen und der parametrisierten Abfrage zu verhindern. Wir verwenden mysqli, um die Datenbankkommunikation in dieser Methode herzustellen. Diese Methode hat einen ähnlichen Arbeitsmechanismus wie die erste Methode. Der Kontrastpunkt sind nur die mysqli-Funktionen, mit denen wir die SQL-Injection verhindern.

Wir zeigen Ihnen ein Beispiel, wie Sie vor SQL-Injection schützen können, während Sie das PDO in PHP verwenden, indem Sie die Emulation vorbereiteter Anweisungen auf false setzen.

Verwenden Sie die vorbereiteten Anweisungen und das PDO, um SQL Injection in PHP zu verhindern

Wir können die vorbereitete Anweisung zusammen mit dem PDO verwenden, um die SQL-Injection in PHP zu verhindern. SQL-Injection tritt auf, wenn die Abfrage und die Daten beim Senden an die Datenbank gemischt werden. Bei dieser Methode geben wir nicht den genauen Wert der Daten in der SQL-Anweisung an. Wir verwenden stattdessen die Platzhalter. Aus diesem Grund werden die parametrisierten SQL-Anweisungen als erste Anforderung an den Server gesendet. Dazu verwenden wir die Funktion prepare(). Wir binden den genauen Wert des Parameters in der zweiten Anforderung an den Datenbankserver. Zu diesem Zweck verwenden wir die Funktion bindValue(). Auf diese Weise senden wir das Programm bei der ersten Anfrage und die Daten bei der zweiten Anfrage. Wenn wir die Daten zusammen mit den SQL-Codes anfordern, kann der Benutzer das Programm ändern und schädliche Codes schreiben. Auf diese Weise wird verhindert, dass schädliche SQL-Codes in den Server eingefügt werden.

Beispielsweise enthält eine Tabelle Benutzer die folgenden Felder und Daten.

+----+-----------+----------+------------+
| id | firstname | lastname | dob        |
+----+-----------+----------+------------+
|  1 | bruce     |  rose    | 1998-02-13 |
|  2 | jeff      |  james   | 2000-03-30 |
+----+-----------+----------+------------+

Es erstellt eine Variable $firstname und weist ihr den Namen bruce zu. Es erstellt eine Variable $sql und schreibt eine Abfrage SELECT * FROM users WHERE firstname =:fname; darauf.

Schreiben Sie nicht den genauen Wert der Daten für firstname. Verwenden Sie stattdessen den Parameter :fname. Verwenden Sie die Variable $pdo, um die Funktion prepare() für die Abfragevariable aufzurufen. Ersetzen Sie den Wert von :fname durch die Variable firstname. Führen Sie die Anweisung mit der Funktion execute() aus. Überprüfen Sie das Ergebnis mit der Funktion fetch(), wenn die Anmeldeinformationen mit der Datenbank übereinstimmen. Wenn dies der Fall ist, zeigen Sie die id, den Vornamen und den Nachnamen der ausgewählten Zeile an.

Das folgende Beispiel zeigt die Verwendung einer vorbereiteten Anweisung. Der Wert des Felds firstname wird in einer Variablen gespeichert, um zu überprüfen, ob der Berechtigungsnachweis übereinstimmt. Wenn die Variable stattdessen schädlichen Code enthalten hätte, würde die Meldung Credentials do no match angezeigt. Dies liegt daran, dass die Funktion prepare() nur die parametrisierte Abfrage akzeptiert und nicht die genauen Daten zulässt. Die Variable $pdo enthält das Objekt der Datenbankverbindung.

Beispielcode:

# php 7.*
<?php
$firstname = "bruce";
$sql = "SELECT * FROM users WHERE firstname =:fname ;";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(":fname", $firstname);
$stmt->execute();
if(!$result = $stmt->fetch(PDO::FETCH_OBJ)){
    echo "Credentials do no match";
} else {
    echo"Id: ".$result->id. " Name: ".$result->firstname." ".$result->lastname;
}
?>

Ausgabe:

Id: 1 Name: bruce rose

Verwenden Sie die Anweisungen Prepared mit der parametrisierten Abfrage, um die SQL-Injection in PHP zu verhindern

Wir können die vorbereitete Anweisung zusammen mit der parametrisierten Abfrage verwenden, um die SQL-Injection in PHP zu verhindern. Wir verwenden das Objekt der Funktion mysqli(), um eine Datenbankverbindung herzustellen. Bei dieser Methode verwenden wir ein Fragezeichen ? als Platzhalter der Daten. Wir verwenden die Funktion prepare() als obige Methode. Wir verwenden die Funktion bind_param(), um die realen Daten im Platzhalter zu binden. Diese Methode folgt einem ähnlichen Arbeitsmechanismus wie die obige Methode.

Stellen Sie beispielsweise eine Datenbankverbindung her, die ein Objekt der Funktion mysqli() erstellt, und weisen Sie es einer Variablen $conn zu. Weisen Sie einer Variable $firstname den Namen jeff zu. Erstellen Sie eine Variable $sql und schreiben Sie eine Abfrage SELECT * FROM users WHERE first name =?;. Verwenden Sie die Variable $conn, um die Funktion prepare() für die Abfragevariable aufzurufen. Platzhalter ersetzen ? mit der Variable $firstname. Führen Sie die Anweisung mit der Funktion execute() aus. Rufen Sie die Funktion get_result() auf, um das Ergebnis in der Variablen $result zu speichern. Überprüfen Sie, ob die Zeile mit der Eigenschaft num_rows vorhanden ist, und geben Sie die Meldung No Rows mit der Funktion exit() zurück, wenn die Bedingung fehlschlägt. Rufen Sie die Methode fetch_assoc() auf und speichern Sie sie in einer while-Schleife in der Variablen $row. Zeigen Sie die id, den Vornamen und den Nachnamen der ausgewählten Zeile an.

Beispielcode:

#php 7.x
<?php
$conn = new mysqli($host, $user, $pwd, $dbName);
$firstname = "jeff";
$sql = "SELECT * FROM users WHERE firstname = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $firstname);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows === 0) exit('No rows');
    while($row = $result->fetch_assoc()) {
    echo"Id: ".$row['id']. " Name: ".$row['firstname']." ".$row['lastname'];
}

Ausgabe:

Id: 2 Name: jeff james

Setzen Sie das Attribut PDO::ATTR_EMULATE_PREPARES auf false, um die SQL-Injection zu verhindern

Die Verwendung vorbereiteter Anweisungen in PDO reicht möglicherweise nicht aus, um die SQL-Injection zu verhindern, wenn die PDO-Attribute nicht korrekt festgelegt werden. Wir sollten das Attribut PDO::ATTR_EMULATE_PREPARES auf false setzen, um die Injektion zu verhindern. Wenn wir das Attribut auf true setzen, emuliert das PDO nur die vorbereiteten Anweisungen, anstatt sie zu verwenden. Somit ist das System für SQL-Injection anfällig.

Erstellen Sie beispielsweise eine PDO-Verbindung zur Datenbank in einer Variablen $pdo. Verwenden Sie die Variable, um die Funktion setAttribute() aufzurufen. Setzen Sie das Attribut PDO::ATTR_EMULATE_PREPARES auf false.

Codebeispiel:

#php 7.x
<?php
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
?>
Subodh Poudel avatar Subodh Poudel avatar

Subodh is a proactive software engineer, specialized in fintech industry and a writer who loves to express his software development learnings and set of skills through blogs and articles.

LinkedIn