2013-02-15 44 views
1

我目前正在編寫一個專注於安全性的php框架。我使用查詢生成器來生成SQL語句,以便它不綁定到MySQL。 (或一般的SQL)我發現用戶可以注入行名的某些可能性,所以它必須以某種方式逃避它們。由於查詢生成器的工作原理,我很遺憾不能使用預準備語句。我怎樣才能解決這個問題?mysql消毒行名

編輯:

該系統適用於例如這樣的:db::select()-from('Tablename')->that('rowname')->run()。而且恐怕有一個用戶可以做類似that($_GET['foo'])之類的東西。我可以忍受這一點,但我認爲必須有一種方法來這樣做

+0

在準備好的語句中使用'mysqli_'或'PDO'? – Kermit 2013-02-15 16:20:41

+0

你可以顯示一些代碼或給出具體用例與你正在使用什麼行名稱?如果你不能使用準備好的語句,那麼你正在做一些非常錯誤的事情。 – mkaatman 2013-02-15 16:21:21

+0

系統的工作原理如下: – edave 2013-02-15 16:31:54

回答

0

要逃避反抽,你必須double it。這裏是我的班級的功能

private function escapeIdent($value) 
{ 
    if ($value) 
    { 
     return "`".str_replace("`","``",$value)."`"; 
    } else { 
     $this->error("Empty value for identifier (?n) placeholder"); 
    } 
} 

//example: 
$db->query("UPDATE users SET ?u=?s", $_POST['field'], $_POST['value']); 

所以,它會創建一個語法正確的標識符。

但它總是更好whitelist它,因爲可以有一個字段,雖然用正確的名稱,用戶沒有訪問權限。 (因此,從這個角度來看,基於模式的解決方案仍然很危險。想象一下,role字段的值爲admin,用於查詢我的示例)
爲了這個目的,我在我的類中有兩個函數,它們都接受允許值的數組。

+0

它讓我害怕了一點,看不到這個簡單解決方案的任何明顯的攻擊。我會執行它。 (白名單已經是上面圖層的一部分,我的ORM,但是可以單獨使用)謝謝! – edave 2013-02-15 19:41:00

-1

由於查詢生成器的工作原理,我很遺憾不能使用預處理語句。我怎樣才能解決這個問題?

如果您不能使用查詢參數,則更改查詢構建器以在將它們插入SQL表達式之前對其參數應用轉義。

很多人都提倡正確的查詢參數,但逃避也是安全IF你正確和一貫做到這一點。

參考mysqli::real_escape_string()


重新發表您的評論,好的,我明白你要去哪裏了。我很困惑,因爲你說「行名」,這不是正確的術語。您必須表示列名稱

是的,你說得對,任何MySQL API都沒有函數來正確地轉義表或列標識符。轉義函數僅用於字符串文字和日期文字。

當不可信輸入名稱表或列時,保護SQL查詢的最佳方法是使用白名單。也就是說,根據已知表名或列名稱列表來測試參數,您可以手動對其進行編碼,也可以從DESCRIBE table中找到它。

見白名單的例子,在我過去的答案:

+0

我已經使用mysqli :: real_escape_string(),但我無法看到如何將其應用於表/行名稱,因爲它不會過濾'我使用的字符' – edave 2013-02-15 16:58:22