2011-05-16 99 views
12

PHP變量在我以前的帖子請問如何從一個數組(PHP Variables made with foreach)我有幾個答案創建變量和我測試提取物(),但我已經看到了反對一些出於安全原因。如何安全地創建與提取

現在,這裏我的問題是如何使用提取的安全的方式從$ _ POST擁有這是使用jQuery做連載的陣列。

隨着安全我的意思是,如果用戶輸入了錯誤的數據,羊城通可以照顧與沒有問題。

PHP的網站在提取命令一個小警告說以下內容:

不要在不可信 數據提取物(),比如用戶輸入(即$ _ GET, $ _FILES等)。如果你這樣做,例如,如果你想運行舊代碼 依賴於register_globals的 暫時 ,請確保您使用非覆蓋extract_type參數 值,如EXTR_SKIP的 一個,並意識到 ,你應該在相同的提取 在php.ini中定義了 variables_order。

它警告使用,但至少不提供如何以安全方式解決提取用戶的示例。

+1

出了什麼問題簡單地使用$ _ POST [ '關鍵']或$ _GET [ '關鍵']? – Cfreak 2011-05-16 21:44:16

+0

除了近200個變量之外沒有任何區別。但既然Marc B的回答我認爲我必須輸入每一個。 – 2011-05-16 21:46:37

+2

只是爲了跟進Marc B的評論。大量變量是使用完整變量名稱的一個很好的理由。您可以立即在代碼中的任何地方看到它,並知道將它作爲不安全的數據處理。 – Cfreak 2011-05-16 22:00:50

回答

10

最好的辦法是不使用extract()可言。從PHP編寫安全代碼相當於溼廁紙的日子來看,這是一個糟糕的設計決定。

這可能是痛苦的,但它遠不如寫出來的長序列:

$var1 = $_POST['var1']; 
$var2 = $_POST['var2']; 
etc... 

或只是在代碼中使用$_POST['var1']和公司無處不在。

一旦你開始使用提取物,你給惡意用戶的潛在方法到你的代碼,無論你有多少時間/精力投入到它。你不要在銀行金庫門上鑽一個洞,因爲每次開門都讓人有錢就太煩人了。一旦出現漏洞,就會被利用。

extract($_POST, EXTR_PREFIX_ALL, 'unique_prefix'); 

爲什麼提取物可能是危險的原因是一樣的使用register_globals

+2

謝謝你的歷史。不知道。 – 2011-05-16 21:45:04

7

不要使用extract(),只需在POST/GET上使用foreach()來創建自己的數組/對象。當你的代碼開始變大時,extract()將會成爲噩夢來進行調試。

+0

Foreach?只要'$ myVar = $ _POST;'如果你不喜歡標準的$ _POST數組。如果您從陣列中獲得了一個維度,則與解壓縮一樣具有相同的漏洞問題。 – 2014-01-03 08:55:02

6

這隻要您使用前綴並不在其他變量存在足夠安全。

+0

所以提取是安全的使用*如果你使用一個獨特的前綴? – TheCrazyProfessor 2017-03-29 09:48:57

1

沒有什麼錯extract如果你只使用它的已知輸入變量的部分提取。這不是最好的語法,但可用:

extract(array_intersect_key($_POST, 
     array_flip(array("var1", "var2", "var3", "var4")))); 

這減少了可能的$ _POST變量,不會提取意外的東西。一般的好處是,您仍然可以使用array_map來應用一些過濾功能。在某些設置中,與單個變量複製相比,它減少了代碼混亂。

1

什麼是關於使用一個簡單的foreach,而不是提取物():

foreach($_POST as $k => $v) $$k = $v; 

所以,你可以處理在$$k = $v;部分增加了一些安全代碼。

+0

相同的安全問題,因爲任何人都可以在瀏覽器中操作內嵌的數組中的數組的鍵和值。 – 2014-01-03 08:56:01

1

在全球範圍內使用提取物和_REQUEST,_GET,_POST,_COOKIE危險。

但是,如果僅允許使用過濾機制使用的變量並取消設置來自外部的所有變量,則可以使用提取。例如,如果您直接將_REQUEST,_GET,_POST,_COOKIE放入一個函數中,該函數將執行extract()內部並僅放出您在return()中定義的函數,那麼您也很安全。因爲任何其他提取 - 包括來自惡意嘗試的變量 - 都將保留在函數範圍內,並且無法執行任何操作。因此,extract()尊重範圍 - 在函數內部提取的任何東西都會保留在該函數內,因此,在類方法內部提取的任何內容都將保留在該類方法的範圍內,並且不會在任何地方讓出它們。

這意味着在全局範圍和功能/對象範圍內,您可以安全地使用提取信任數據。

假設的$ args是一個關聯數組:


function funny($args) 
{ 
    extract($args); 

    // Hereon you can use the variables normally and they will stay in function scope 

} 

您的變量將保持功能的範圍內。

同爲一類方法:


class berserker 
{ 
    public function funny($args) 
    { 
     extract($args); 

     // Hereon you can use the variables normally and they will stay in method scope 

    } 

} 
相關問題