2012-08-02 49 views
0

我知道參數化查詢,但我有一對夫婦的舊網站中,我用這個方法清理用戶輸入:

<? 
mysql_query(sprintf('SELECT col1 FROM table1 WHERE id = %d', $tainted)); 
?> 

注意周圍有沒有%d報價。 $tainted是否有任何值可能導致此類查詢出現意想不到的結果?給出語法錯誤很容易,但我不在乎太多。

我對類似的UPDATE和DELETE查詢使用了相同的方法。我是否應該回去修復所有舊查詢,或者在這裏沒有漏洞?

回答

4

不,這不是一個漏洞。

但它是一個潛在漏洞:如果一些維護程序員決定執行一個小的變化,而忘記該變量可被污染,或者,若變量的數據類型是從整數改變爲字符串(和說明符來%s )在路上 - 那麼會有麻煩。

最好不要去那裏開始(但從實際的角度來看,如果加強這個遺留代碼的防禦是值得的,也不明顯)。

+0

謝謝。我很擔心,因爲PHP-sprintf認爲數字可能會出現奇怪的字節混合。 – Andreas 2012-08-02 22:27:27

1

作爲輸入它看起來足夠安全,但從用戶體驗的角度來看,這絕對不可取,因爲如果輸入與所需參數不匹配,您將無法向用戶提供詳細信息如果id屬性。

3

要回答你的問題,在其中您呈現的方式使用sprintf的,應避免任何SQL注入,因爲任何非INT值經由%d強制轉換爲十進制將簡單地取0值:

$ -> php -r "echo sprintf('update table where id = %d', 'drop databases');" 
update table where id = 0 

但是,如果我沒有試圖說服你使用PDO API,更具體地說,是prepared statements,那麼我會失職。我相信mysqli API也準備了語句,但我從未使用它們,只使用過PDO準備,或者是諸如Doctrine或Propel的ORM。

0

從理論上講,它不應該是脆弱的,因爲sprintf()不會插入變量,如果它不是數字。

但是,這並不意味着它是正確的。它可能仍然會導致錯誤,可能會破壞您的代碼。

無論這個問題是否存在漏洞,我都強烈建議完全切換掉mysql_xx()函數。

舊的MySQL庫已被廢棄(請參閱the PHP manual pages的註釋),建議切換到PDO或mysqli_xx庫。

PDO和MySQL都有一個名爲Prepared Queries的功能,它完全可以實現你在這裏實現的功能,這是一個比sprintf()更好的解決方案。刪除需要轉義SQL的所有變量。

希望有所幫助。