2012-05-01 60 views
1

我對參數化查詢幾個基本問​​題我應該將輸入清理爲參數化查詢嗎?

考慮以下代碼:

$id = (int)$_GET['id']; 
mysql_query("UPDATE table SET field=1 WHERE id=".$id); 

現在使用參數化查詢

$sql = "UPDATE table SET field=1 WHERE id=?"; 
$q = $db->prepare($sql); 
$q->execute(array($_GET['id'])); 

我的問題,同樣的事情是:

  1. 是否有任何情況下,第一個代碼(即與(int) cast)是不安全的?
  2. 是代碼的第二件OK,或者我應該也投$_GET['id']爲int?
  3. 是否有任何已知的所述第二片的代碼的漏洞?也就是說,如果我正在使用第二個查詢,是否有任何方法可以執行SQL攻擊?

回答

3
  1. 是否有任何情況,其中第一代碼(即與(int)的流延)是不安全的?

    我不是PHP專家,但我認爲應該不是。這並不是說PHP沒有可以在這裏被利用的錯誤(已知或尚未被發現)。

  2. 是代碼的第二件OK,或者我應該也投$ _GET [「身份證」]爲int?

    同樣,第二段代碼應該是絕對正確的 - 即使數據類型是字符串,MySQL也不會因爲它是一個參數而對它進行評估,因此它只是被視爲文字值。但是,肯定是沒有壞處也執行轉換(這將避免在MySQL的操作參數的任何瑕疵) - 我建議你做兩個。

    編輯 - @Tomalak提出了一個非常好的關於可能導致不正確數據的建議,並建議先驗證您的輸入是否具有完整性檢查,如is_numeric();我衷心同意。

  3. 是否有任何已知的所述第二片的代碼的漏洞?也就是說,如果我正在使用第二個查詢,是否有任何方法可以執行SQL攻擊?

    據我所知。

2
  1. (int)當轉換失敗會產生0。這可能會導致更新錯誤的記錄。此外,當查詢變得越來越複雜時,它就會馬虎似的,並且是一個公開的邀請,可以「忘記」正確的類型轉換。
    這是目前的形式安全(針對SQL注入,不是針對更新錯誤的記錄),但我還是不推薦。一旦查詢變得越來越複雜,無論如何你都必須使用準備好的語句,所以只需從一開始就做 - 也是爲了一致性。

  2. 這也是馬虎。該參數將以字符串的形式傳輸到數據庫,數據庫將嘗試投射它。這是安全的(針對SQL注入),但是除非您確切知道數據庫服務器在傳遞無效數據時如何作出反應,否則應該預先對值進行清理(is_numeric()並轉換)。

  3. (除非有在PDO的錯誤,那就是。)

作爲一個經驗法則:

  • 不要選中數據傳遞到數據庫並期待正確的事情發生。
  • 請勿明知故障傳遞無效數據並相信其他系統以某種方式作出反應。自己進行健康檢查和錯誤處理。
  • 不要讓「哦,那將轉換爲0,我也沒有ID 0的記錄,所以沒關係。」你的思維過程的一部分。
+0

re#3 - ...或MySQL。 – eggyal

+0

@eggyal極不可能,但是。 – Tomalak

+0

我擔心可能發生的攻擊,而不是輸入的正確性,但這仍然是一個好的方面。 (但是請注意,'is_numeric'也允許浮動) – nico

相關問題