簡體   English   中英

如何保護ODBC查詢免受SQL注入

[英]How to protect an ODBC query from SQL injection

保護此查詢免受sql注入的最佳方法是什么? 這個例子只是一個例子,我在互聯網上讀了幾篇文章,但是無法理解參數化查詢。 任何指向有用文章的鏈接都將獲得投票,但我認為看到這個示例將對我有最大的幫助。

$id = $_GET["id"];
$connection = odbc_connect("Driver={SQL Server};Server=SERVERNAME;Database=DATABASE-NAME;", "USERNAME", "PASSWORD");
$query = "SELECT id firstname secondname from user where id = $id";
$result = odbc_exec($connection, $query);
while ($data[] = odbc_fetch_array($result));
odbc_close($connection);

謝謝,

編輯:我沒有使它顯而易見,但我使用的是SQL Server,而不是mysql。 這只是一個例子,它並不總是我要搜索的數字。 如果答案使用參數化查詢(如許多人所建議的那樣),並且對於所有查詢都是相同的,而不是針對不同類型的用戶輸入的不同類型的驗證,那將是很好的。

我認為PDO對象是最好的。

簡而言之,這是如何使用它們。

$databaseConnection = new PDO('mysql:host='. $host .';dbname=' . $databaseName, $username, $password);

$sqlCommand = 'SELECT foo FROM bar WHERE baz=:baz_value;';
$parameters = array(
    ':baz_value'    => 'some value'
);

$preparedStatement = $databaseConnection->prepare($sqlCommand);
$preparedStatement->execute($parameters);

while($row = $preparedStatement->fetch(PDO::FETCH_ASSOC))
{
    echo $row['foo'] . '<br />';
}

您將為SELECT標准輸入的值將替換為以冒號開頭的參數(例如:field_value )。 然后為參數分配數組中分別傳遞的值。

我認為這是處理SQL查詢的更好的方法。

參數與查詢分開發送到數據庫,並防止SQL注入。

首先,請謹慎使用查詢中使用的變量,尤其是那些來自諸如$ _GET,$ _POST,$ _COOKIE和$ _FILES之類的外部源的變量。 為了在查詢中使用變量,您應該:

  • 將數字數據轉換為整數或浮點數(以適當為准)
  • 使用適當的轉義符轉義其他數據

mysql數據庫的一個簡單示例:

$id = $_GET["id"];     // contains: OR 1 = 1
$name = $_GET["name"]; // contains: ' OR '' ='
$query = "SELECT * FROM table WHERE id = " . intval($id) . " AND name = '" . mysql_real_escape_string($name) . "'";
// SELECT * FROM table WHERE id = 0 AND name = '\' OR \'\' =\''

對於其他數據庫,轉義實踐有所不同。 但通常你應該逃脫'用字符'' ,所以:

$id = $_GET["id"];     // contains: OR 1 = 1
$name = $_GET["name"]; // contains: ' OR '' ='
$query = "SELECT * FROM table WHERE id = " . intval($id) . " AND name = '" . str_replace("'", "''", $name) . "'";
// SELECT * FROM table WHERE id = 0 AND name = ''' OR '''' ='''

話雖如此,也許您可​​能想要切換到PDO 它允許您使用准備好的語句 ,PDO驅動程序會進行所有轉義。

使用准備好的語句。 首先使用odbc_prepare()函數構建一條語句,然后將參數傳遞給它,然后使用odbc_execute()執行它。

這比自己轉義字符串要安全和容易得多。

劉易斯·巴塞特(Lewis Bassett)關於PDO的建議很好,但是可以在ODBC中使用預准備的語句,而不必切換到PDO。

示例代碼,未經測試!

try {
  $dbh = new PDO(CONNECTION_DETAILS_GO_HERE);
  $query = 'SELECT id firstname secondname from user where id = :id';
  $stmt = $dbh->prepare($query);
  $stmt->bindParam(':id', $id, PDO::PARAM_STR);
  $result = $stmt->execute();
  $data = $stmt->fetchAll();
} catch (PDOException $e)
  echo 'Problem: ', $e->getMessage;
}

注意:$ e-> getMessage(); 可能會公開您不想公開的內容,因此您可能希望在代碼上線時在該行上執行其他操作。 但是,它對於調試很有用。

編輯:不確定是否要使用PDO或ODBC示例,但兩者基本相同。

編輯:如果您不贊成我,請發表評論並告訴我原因。

mysql變體帶有一種稱為mysql_real_escape_string的方法,該方法適用於所針對的SQL版本。 您能做的最好的事情是編寫一個轉義ID的方法。 重要的是, 您的轉義方法適用於目標數據庫 您也可以對數字輸入進行基本類型檢查,例如is_numeric,它將立即拒絕SQL字符串注入。

請參見如何使用PHP在SQL Server中轉義字符串? 並點擊一些相關鏈接以獲取明確的示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM