Přejděte na druhý řádek v zobrazení kódu, hned za soubor include pro připojení, a přidejte funkci GetSQLValueString() na začátek kódu následovně:
<?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; } } ?>
Problém
Některé databáze umožňují odeslání několika příkazů SQL v jednom dotazu. Proto existují potenciální bezpečnostní rizika při předávání parametrů v řetězci dotazu do dynamicky generovaného databázového dotazu.Hackeři by mohli zkusit upravit proměnné URL nebo formuláře v dynamickém dotazu připojením škodlivých příkazů SQL k existujícím parametrům.Tento postup se často označuje jako útok prostřednictvím injektáže SQL. Některé z kódů chování serveru vytvořených aplikací Dreamweaver je třeba změnit, aby se snížilo riziko útoků prostřednictvím injektáže SQL. Další doplňující informace o injektáži SQL najdete v tomto článku webové encyklopedie Wikipedia. (Viz 201713)
Poznámka: Problém popsaný v tomto technickém článku byl opraven v aktualizaci aplikace Dreamweaver 8.0.2.
Tento technický článek pokrývá chování PHP serveru v aplikaci Dreamweaver.Existují samostatné technické články pro serverová chování ColdFusion, ASP VBScript, ASP JavaScript a JSP.Chování serveru ASP.NET nejsou ovlivněna.
Řešení
Když řetězci dotazu umožníte předat parametr, zajistěte, aby byly předány pouze očekávané informace. Adobe vytvořilo aktualizaci aplikace Dreamweaver 8.0.2, která snižuje riziko útoků typu SQL injection.Tyto opravy budou začleněny do všech budoucích vydání aplikace Dreamweaver.Po aktualizaci aplikace Dreamweaver 8 budete muset znovu použít chování serveru na stránky, které je používají, a znovu nasadit tyto stránky na váš server.
Zbytek tohoto technického článku dokumentuje, jak ručně upravit kód aplikace Dreamweaver MX 2004 pro zabránění útokům vkládání SQL s PHP serverovým modelem.Chování serveru, která jsou zranitelná vůči těmto útokům, jsou uvedena níže spolu s opravami:
Sada záznamů s filtrem
Nefiltrované sady záznamů není třeba měnit, avšak filtrované sady záznamů ano. V níže uvedeném příkladu je sada záznamů aplikace Dreamweaver MX 2004 s názvem "rs_byDate" filtrována podle hodnoty data předané z parametru URL.Zvýrazněný kód níže je to, co je třeba změnit:
<?php $colname_rs_byDate = "1"; if (isset($_GET['relDate'])) { $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); ?>
Pro ochranu sady záznamů před útoky vkládání SQL by měla být vytvořena vlastní funkce GetSQLValueString() v horní části stránky.Tato funkce ověřuje datový typ parametru dotazu.Jakmile je funkce vytvořena, aktualizujte kód sady záznamů tak, aby používal funkci GetSQLValueString().
Upravený kód:
$colname_rs_byDate = $_GET['relDate'];
Aktualizujte kód sady záznamů tak, aby vytvořil řetězec SQL pomocí funkce GetSQLValueString() vytvořené výše.Aktualizujte hodnotu proměnné $query_rs_byDate:
Původní kód:
$query_rs_byDate = sprintf("SELECT * FROM albums WHERE relDate = '%s'", $colname_rs_byDate);
Změněný zabezpečený kód:
$query_rs_byDate = sprintf("SELECT * FROM albums WHERE relDate = %s", GetSQLValueString($colname_rs_byDate, "date"));
Serverové chování Insert, Update a Delete Record a průvodce Record Insertion Form
Serverové chování Insert, Update a Delete Record a průvodce Record Insertion Form již používají funkci GetSQLValueString(), proto je třeba je upravit, aby se zabránilo útokům SQL injection.Jediné změny, které jsou potřeba, jsou ve funkci GetSQLValueString().
Zde je původní kód.Řádek, který je třeba změnit, je zvýrazněn žlutě:
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; } }
Aktualizujte definici proměnné $theValue:
Původní kód:
$theValue = (!get_magic_quotes_gpc()) ? addslashes($theValue) : $theValue;
Upravený zabezpečený kód:
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue; $theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);
Chování serveru na základě přihlášení uživatele
Zde jsou kroky k opravě chování serveru pro přihlášení uživatele:
Upravte kód, který vytváří přihlašovací dotaz SQL.
Původní kód:
$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));
Upravený zabezpečený kód:
$LoginRS__query=sprintf("SELECT username, password FROM login WHERE username=%s AND password=%s", GetSQLValueString($loginUsername, "text"), GetSQLValueString($password, "text"));
Chování serveru na základě kontroly nového uživatele
V případě chování serveru na základě kontroly nového uživatele je třeba na stránku nejprve přidat chování serveru na základě vložení záznamu. Funkce GetSQLValuesString() je součástí chování serveru Vložit záznam. Vše, co je třeba udělat, je aktualizovat funkci GetSQLValuesString() tak, aby lépe zvládala SQL injection, a aktualizovat chování serveru Zkontrolovat nového uživatele tak, aby používalo tuto funkci při předávání parametru.
Upravte kód pro vytvoření přihlašovacího dotazu SQL tak, aby používal funkci GetSQLValuesString() k předávání parametrů. V horní části stránky najděte kód v sekci začínající // *** Redirect if username exists.
Původní kód:
$LoginRS__query = "SELECT username FROM login WHERE username='" . $loginUsername . "'"
Upravený zabezpečený kód:
$LoginRS__query = sprintf("SELECT username FROM login WHERE username=%s", GetSQLValueString($loginUsername, "text"));
Sada hlavní stránky a stránky podrobností
V případě aplikačního objektu sady hlavní stránky a stránky podrobností jsou změny hlavně v sadě záznamů, kterou aplikace Dreamweaver vytvoří pro stránku podrobností. Pokud nemáte filtrovanou sadu záznamů na hlavní stránce, není třeba provádět žádné změny hlavní stránky. Pokud máte filtrovanou sadu záznamů, pak se podívejte na část sada záznamů s filtrem pro aktualizaci kódu sady záznamů.
Dreamweaver vytváří filtrovanou sadu záznamů na stránce podrobností, takže je třeba aktualizovat kód této sady záznamů, aby používal funkci GetSQLValueString() k předávání parametrů a funkci sprintf() k vytvoření řetězce SQL.
Aktualizujte kód deklarace proměnné a vytvořte dotaz SQL pomocí funkce GetSQLValuesString().
Původní kód:
$recordID = $_GET['recordID']; $query_DetailRS1 = "SELECT * FROM albums WHERE ID = $recordID";
Upravený zabezpečený kód:
$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"));
Průvodce formulářem pro aktualizaci záznamu
Další informace
Další informace o útocích SQL injection naleznete v následujícím článku: článek na Wikipedii o útocích SQL injection.
Bezpečnostní bulletin společnosti Adobe: APSB 06-07 Dreamweaver Server Behavior SQL Injection vulnerability.
Tvorba nádherných webů v aplikaci Dreamweaver
Vytvářejte, kódujte a spravujte dynamické weby pomocí výkonného všestranného nástroje.