PHP-Server-Verhalten vor SQL-Injection-Schwachstellen schützen

Zuletzt aktualisiert am 27. April 2021

Problem

Mit einigen Datenbanken können Sie mehrere SQL-Anweisungen in einer einzelnen Abfrage senden. Daher bestehen potenzielle Sicherheitsrisiken, wenn du Parameter in einer Abfragezeichenfolge an eine dynamisch generierte Datenbankabfrage übergibst.Hacker könnten versuchen, URL- oder Formular-Variablen in einer dynamischen Abfrage zu modifizieren, indem sie schädliche SQL-Anweisungen an vorhandene Parameter anhängen.Dies wird häufig als Sicherheitsrisiko durch Einschleusung von SQL-Befehlen bezeichnet. Einige der Serververhaltencodes, die von Dreamweaver erstellt wurden, müssen geändert werden, um das Sicherheitsrisiko durch Einschleusung von SQL-Befehlen zu reduzieren. Weitere Informationen zum Sicherheitsrisiko durch Einschleusung von SQL-Befehlen finden Sie im Wikipedia-Artikel. (Verweis 201713)

Hinweis: Das in dieser TechNote beschriebene Problem wurde in Dreamweaver 8.0.2 Updater behoben.

Diese TechNote behandelt die PHP-Server-Verhalten von Dreamweaver.Es gibt separate TechNotes für die ColdFusion-, ASP VBScript-, ASP JavaScript- und JSP-Server-Verhalten.Die ASP.NET-Server-Verhalten sind nicht betroffen.

Lösung

Wenn Sie zulassen, dass ein Abfragestring einen Parameter übergibt, stellen Sie sicher, dass nur die gewünschten Informationen übermittelt werden. Adobe hat einen Dreamweaver 8.0.2 Updater erstellt, der das Risiko von SQL-Injection-Angriffen reduziert.Diese Korrekturen werden in alle zukünftigen Versionen von Dreamweaver integriert.Nach der Aktualisierung von Dreamweaver 8 musst du die Server-Verhalten auf die Seiten, die sie verwenden, erneut anwenden und diese Seiten erneut auf deinem Server bereitstellen.

Der Rest dieser TechNote dokumentiert, wie du Dreamweaver MX 2004-Code manuell bearbeitest, um SQL-Injection-Angriffe mit dem PHP-Server-Modell zu verhindern.Serververhalten, die für diese Angriffe anfällig sind, sind unten aufgeführt, zusammen mit Korrekturen:

Datensatz mit einem Filter

Ungefilterte Datensatzgruppen müssen nicht geändert werden, aber gefilterte Datensatzgruppen müssen geändert werden. Im folgenden Beispiel wird ein Dreamweaver MX 2004-Recordset namens "rs_byDate" nach einem Datumswert gefiltert, der von einem URL-Parameter übergeben wird.Der hervorgehobene Code unten ist das, was geändert werden muss:

<?php $colname_rs_byDate = &quot;1&quot;; if (isset($_GET[&apos;relDate&apos;])) { $colname_rs_byDate = (get_magic_quotes_gpc()) ? $_GET['relDate'] : addslashes($_GET['relDate']); } mysql_select_db($database_dreamqa2, $dreamqa2); $query_rs_byDate = sprintf("SELECT * FROM albums WHERE relDate = '%s'", $colname_rs_byDate); $rs_byDate = mysql_query($query_rs_byDate, $dreamqa2) or die(mysql_error()); $row_rs_byDate = mysql_fetch_assoc($rs_byDate); $totalRows_rs_byDate = mysql_num_rows($rs_byDate); ?>

Um das Recordset vor SQL-Injection-Angriffen zu schützen, sollte eine benutzerdefinierte GetSQLValueString()-Funktion am Anfang der Seite erstellt werden.Diese Funktion überprüft den Datentyp des Abfrageparameters.Nachdem die Funktion erstellt wurde, aktualisiere den Recordset-Code, um die GetSQLValueString()-Funktion zu verwenden.

Gehe zur zweiten Zeile in der Codeansicht, direkt nach der Include-Datei für die Verbindung, und füge die GetSQLValueString()-Funktion am Anfang des Codes wie folgt hinzu:

<?php if (!function_exists("GetSQLValueString")) { function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") { $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue; $theValue = function_exists(„mysql_real_escape_string“) ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue); switch ($theType) { case "text": $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL"; break; case "long": case "int": $theValue = ($theValue != "") ? intval($theValue) : "NULL"; break; case "double": $theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL"; break; case "date": $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL"; break; case "defined": $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue; break; } return $theValue; } } ?>

Entferne den Magic-Quotes-Code, damit Backslashes nicht fälschlicherweise zu GET- und POST-Daten hinzugefügt werden, wenn Magic Quotes auf dem PHP-Server deaktiviert sind.

Ursprünglicher Code:

$colname_rs_byDate = (get_magic_quotes_gpc()) ? $_GET['relDate'] : addslashes($_GET['relDate']);

Geänderter Code:

$colname_rs_byDate = $_GET['relDate'];



Aktualisiere den Recordset-Code, um einen SQL-String mithilfe der oben angelegten Funktion GetSQLValueString() zu erstellen. Aktualisiere den Wert der Variable $query_rs_byDate:

Ursprünglicher Code:

$query_rs_byDate = sprintf("SELECT * FROM albums WHERE relDate = '%s'", $colname_rs_byDate);

Geänderter sicherer Code:

$query_rs_byDate = sprintf("SELECT * FROM albums WHERE relDate = %s", GetSQLValueString($colname_rs_byDate, "date"));

Server-Verhalten für Datensatz einfügen, aktualisieren und löschen und Assistent für Datensatz-Einfügungsformular

Die Server-Verhalten für Datensatz einfügen, aktualisieren und löschen und der Assistent für Datensatz-Einfügungsformular verwenden bereits die GetSQLValueString()-Funktion, daher müssen sie verfeinert werden, um SQL-Injections zu verhindern.Die einzigen erforderlichen Änderungen befinden sich in der GetSQLValueString()-Funktion.

Hier ist der ursprüngliche Code.Die zu ändernde Zeile ist gelb hervorgehoben:

if (!function_exists("GetSQLValueString")) { function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") {$theValue = (!get_magic_quotes_gpc()) ?addslashes($theValue) : $theValue; switch ($theType) { case "text": $theValue = ($theValue != "") ?"'" . $theValue . "'" : "NULL"; break; case "long": case "int": $theValue = ($theValue != "") ?intval($theValue) : "NULL"; break; case "double": $theValue = ($theValue != "") ?"'" . doubleval($theValue) . "'" : "NULL"; break; case "date": $theValue = ($theValue != "") ?"'" . $theValue . "'" : "NULL"; break; case "defined": $theValue = ($theValue != "") ?$theDefinedValue : $theNotDefinedValue; break; } return $theValue; } }

Aktualisiere die Definition der Variable $theValue:

Ursprünglicher Code:

$theValue = (!get_magic_quotes_gpc()) ? addslashes($theValue) : $theValue;

Geänderter sicherer Code:

$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue; $theValue = function_exists(„mysql_real_escape_string“) ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);

Serververhalten „Benutzer anmelden“

Hier sind die Schritte zur Behebung des Log In User Server-Verhaltens:

Erstelle eine GetSQLValueString()-Funktion wie in Recordset mit Filter oben beschrieben.

Ändere den Code, der die Login-SQL-Abfrage erstellt.



Ursprünglicher Code:

$LoginRS__query=sprintf("SELECT username, password FROM login WHERE username='%s' AND password='%s'", get_magic_quotes_gpc() ? $loginUsername : addslashes($loginUsername), get_magic_quotes_gpc() ? $password : addslashes($password));

Geänderter sicherer Code:

$LoginRS__query=sprintf("SELECT username, password FROM login WHERE username=%s AND password=%s", GetSQLValueString($loginUsername, "text"), GetSQLValueString($password, "text"));

Serververhalten „Neuen Benutzer überprüfen“

Das Serververhalten „Neuen Benutzer überprüfen“ verlangt, dass das Serververhalten „Datensatz einfügen“ zunächst zur Seite hinzugefügt wird. Die GetSQLValuesString()-Funktion ist im Insert Record Server-Verhalten enthalten. Alles was getan werden muss, ist die GetSQLValuesString() zu aktualisieren, um SQL Injection besser zu handhaben und das Check New User Server-Verhalten zu aktualisieren, damit diese Funktion verwendet wird, wenn ein Parameter übergeben wird.

Ändere die erste Zeile in der Funktion, um die GetSQLValuesString()-Funktion wie in Definition der Variable $theValue aktualisieren beschrieben zu aktualisieren.

Ändere den Code, um die Anmelde-SQL-Abfrage zu konstruieren und die GetSQLValuesString() zu verwenden, um Parameter zu übergeben.Suche im oberen Bereich der Seite den Code im Abschnitt, der mit // *** Redirect if username exists.



Ursprünglicher Code:

$LoginRS__query = "SELECT username FROM login WHERE username='" . beginnt$loginUsername . "'"



Geänderter sicherer Code:

$LoginRS__query = sprintf("SELECT username FROM login WHERE username=%s", GetSQLValueString($loginUsername, "text"));

Master-Detailseitensatz

Für das Anwendungsobjekt des Master-Detailseitensatzes sind die Änderungen in erster Linie in der Datensatzgruppe, die Dreamweaver für die Detail-Seite erstellt. Wenn Sie keine gefilterte Datensatzgruppe auf der Masterseite sehen, müssen keine Änderungen an der Masterseite vorgenommen werden. Falls du ein gefiltertes Recordset hast, siehe Recordset mit einem Filter, um den Recordset-Code zu aktualisieren.

Dreamweaver erstellt ein gefiltertes Recordset in der Detailseite, daher muss dieser Recordset-Code aktualisiert werden, um eine GetSQLValueString()-Funktion zu verwenden, um Parameter zu übergeben, und sprintf(), um die SQL-Zeichenfolge zu konstruieren.

Erstelle die GetSQLValueString()-Funktion wie in Recordset mit einem Filter oben beschrieben.

Aktualisiere den Code für die Variablendeklaration und konstruiere die SQL-Abfrage mit der GetSQLValuesString()-Funktion.



Ursprünglicher Code:

$recordID = $_GET['recordID']; $query_DetailRS1 = "SELECT * FROM albums WHERE ID = $recordID";



Geänderter sicherer Code:

$colname_DetailRS1 = "-1"; if (isset($_GET['recordID'])) { $colname_DetailRS1 = (get_magic_quotes_gpc()) ? $_GET['recordID'] : addslashes($_GET['recordID']); } $query_DetailRS1 = sprintf("SELECT * FROM albums WHERE ID = %s", GetSQLValueString($colname_DetailRS1, "int"));

Assistent für Datensatz-Aktualisierungsformular

Aktualisiere den Code für das Recordset, das für das Record Update Form erforderlich ist, wie in Schritt 2 von Recordset mit einem Filter beschrieben.

Weitere Informationen

Weitere Informationen zu SQL-Injection findest du im folgenden Artikel: Wikipedia-Artikel über SQL-Injection.

Adobe Security Bulletin: APSB 06-07 Dreamweaver Server Behavior SQL Injection vulnerability.