2012-01-16 154 views
1

我檢查我是否有漏洞的腳本,並感到非常震驚,我用在過去的方式做,這是非常不安全的:

foreach ($_GET as $key => $value){ 
    $$key = $value; 
} 

或更短

extract($_GET); 

我用螢火蟲修改了一些POST/GET變量來匹配我在腳本中使用的名稱。如果名字被正確猜測,他們可以被覆蓋

所以我想我不得不獨自做它的命名是這樣的: $ allowed_vars =

$allowed_vars = array("time","hotfile","netload","megaupload","user","pfda","xyz","sara","amount_needed"); 
    foreach ($_GET as $key => $value) 
     { 
      if (in_array($key,$allowed_vars)) 
       { 
        $$key = $value; 
       } 
     } 

這樣可以節省一些時間不是分別給它們命名。

必須使用什麼樣的自動化?

+4

爲什麼你必須將他們分配到各個變量擺在首位?你不能只使用'$ _GET ['time']'等等嗎? – JJJ 2012-01-16 14:58:22

+2

僅供參考,您會將'$ allowed_vars'放在foreach之外,沒有理由每次都設置它 – 2012-01-16 14:59:04

+0

@Juahana 1.易用性,2.防止轉義。只是編碼風格,這裏不是真正的問題 – Email 2012-01-16 15:09:49

回答

4

我不使用任何自動類型。
我認爲沒有必要自動將請求變量分配給全局變量。
如果它是一個或兩個變量,我可以手動處理它們。
如果還有更多,我寧願將它們保存爲數組成員以便於處理。

但我正在使用某種類似於您的白名單方法。 但不能從POST數據創建全局變量,而是將該數據添加到SQL查詢中。

如在此簡單的輔助功能來生成SET語句:

function dbSet($fields) { 
    $set=''; 
    foreach ($fields as $field) { 
    if (isset($_POST[$field])) { 
     $set.="`$field`='".mysql_real_escape_string($_POST[$field])."', "; 
    } 
    } 
    return substr($set, 0, -2); 
} 

$id  = intval($_POST['id']); 
$fields = explode(" ","name surname lastname address zip fax phone"); 
$query = "UPDATE $table SET ".dbSet($fields)." stamp=NOW() WHERE id=$id"; 
+0

你最後的論點有一些東西。我會重新考慮我的編碼風格。 – Email 2012-01-16 15:19:22

+0

@Email:這是一個普遍的例子,當然,你仍然想確保你有預期的價值;就像一個zip文件真的是一個zip文件等等。另外,如果你想使用null值,你需要稍微改變它。 – Umbrella 2012-01-16 15:50:55

0

根據我的經驗,您不應該使用$$$_REQUEST數組中的數據轉換爲變量,因爲它可以覆蓋當前範圍內保存的變量。

相反,您應該考慮讓一個請求對象或數組在其中過濾數據並只訪問所需的命名變量。這樣,您不必繼續擴展您允許的變量名稱並仍然保持安全。

的ZF例如有一個請求對象,他們建議使用輸入濾波器對這個數據時: http://framework.zend.com/manual/en/zend.filter.input.html

0

可以使用提取功能以更安全的方式:

extract($_REQUEST, EXTR_SKIP); 

這不會覆蓋您的代碼中已經存在的變量。有關可以使用的其他參數,請參閱here

+2

然而,它仍然是一個類似於register_globals的漏洞 - 如果您沒有定義變量$ admin對於普通用戶,可以這樣創建它。 – 2012-01-16 15:02:44

+0

@ Col.Shrapnel當然,那麼你必須運用常識和一些開發人員的技能來避免這種情況.. :) – SERPRO 2012-01-16 15:06:38

+1

我寧願避免extract()函數 – 2012-01-16 15:07:46

3

通過完全不提取它們,您可以節省更多時間。只需從$ _GET數組中使用它們即可。這樣做的好處不僅僅是避免與腳本變量(或更糟糕的情況)發生衝突,而且當您添加請求參數時,您不必更新「自動操作」。

當我用POST數據的工作,從一個形式,我經常處理每一個明確的:

$data = array(); 
$data['field1'] = someSaniFunction($_POST['field1']); 
$data['field2'] = someOtherFunction($_POST['field2']); 
... 

這樣,我保證每場得到妥善處理,只有我期待的字段感動。

+0

我想用1個字改寫自動機比另外的時間用$ _POST ['something'] 2+ times – Email 2012-01-16 15:14:26