2015-07-19 34 views
0

我發現這段代碼在這裏: http://php.net/manual/de/reserved.variables.get.php

想用它來使我的代碼更安全。我在我的項目中使用了很多$ _GET var。

請,如果可能的話,我希望你的專業人士看看,看看這段代碼是否可以增強或有任何問題。

還有就是要防止惡意注入和選項$ _GET輸入插入默認值一個聰明的辦法:

<?php 
// Smart GET function 
public function GET($name=NULL, $value=false, $option="default") 
{ 
    $option=false; // Old version depricated part 
    $content=(!empty($_GET[$name]) ? trim($_GET[$name]) (!empty($value) && !is_array($value) ? trim($value) : false)); 
    if(is_numeric($content)) 
     return preg_replace("@([^0-9])@Ui", "", $content); 
    else if(is_bool($content)) 
     return ($content?true:false); 
    else if(is_float($content)) 
     return preg_replace("@([^0-9\,\.\+\-])@Ui", "", $content); 
    else if(is_string($content)) 
    { 
     if(filter_var ($content, FILTER_VALIDATE_URL)) 
      return $content; 
     else if(filter_var ($content, FILTER_VALIDATE_EMAIL)) 
      return $content; 
     else if(filter_var ($content, FILTER_VALIDATE_IP)) 
      return $content; 
     else if(filter_var ($content, FILTER_VALIDATE_FLOAT)) 
      return $content; 
     else 
      return preg_replace("@([^a-zA-Z0-9\+\-\_\*\@\$\!\;\.\?\#\:\=\%\/\ ]+)@Ui", "", $content); 
    } 
    else false; 
} 

/* 
DEFAULT: $_GET['page']; 
SMART: GET('page'); // return value or false if is null or bad input 
*/ 
?> 

來源:http://php.net/manual/de/reserved.variables.get.php

+2

有沒有這樣的事情,「一個字符串安全」的單一代碼,因爲這一切都取決於你正在使用的變量*爲*:你是把數據庫,回聲在HTML中,或也許都是,或者完全是其他的東西?逃避應該總是針對特定的數據片段,在特定的使用環境中進行;它不能在整個用戶輸入中一般地完成。 – IMSoP

+1

這個函數也有bug,例如,is_bool和is_float永遠不會返回true,因爲$ _GET中的所有內容都是一個字符串,正如從trim()返回的所有內容一樣。這些函數不會查看字符串的內容,只是變量的類型。它會返回null,而不是false,因爲'else false'並不意味着什麼(我很驚訝它不是語法錯誤)。 – IMSoP

+0

可能重複[如何防止SQL注入在PHP?](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) – vascowhite

回答

0

的想法是舊的,通常實現。我個人更喜歡一個變體,你也可以指定預期的參數類型。沒有這些,我認爲這種方法沒有意義,因爲函數只能對它得到的結果做出反應。

以「is_bool」爲例。這一點目前沒有任何意義。 php永遠不會提供一個布爾值,它會總是將參數解釋爲字符串,如果指定了內容「false」或「true」,或者是0和1,或者甚至是空字符串。所以這個條件將永遠不會會見。

以「is_numeric」情況爲另一個示例。當然,可以將一個字符串變量轉換爲乾淨的數字類型。但是,基於正則表達式替換的想法是什麼?如果內容結果爲true作爲is_numeric()調用的返回值,那麼那裏肯定只有數字。每個定義。這假定這裏實際上的含義是is_int(),因爲否則那個條件分支會阻止下面兩個根本沒有任何意義的分支。

我在這裏想念的是顯式轉換。爲什麼所有的努力,如果你然後不轉換爲明確的變量類型?


如果指定的函數預期的類型這將是不同的:

// returns a boolean 
$isSomeFlagSet = GET('bool_flag', 'bool'); 
// returns an integer or throws an exception 
$numberOfHits = GET('number_of_hits', 'int'); 
// returns a string, maybe trimmed for convenience 
$userName = GET('user_name', 'string'); 

你甚至延長該非內建類型的增加了它的價值:

// returns a string which is guaranteed to be a valid url 
$baseUrl = GET('base_url', 'url'); 
// returns maybe a two char language code (e.g.'en') or throws an exception 
$userLang = GET('lang', 'langcode'); 
// you could add a type 'json' which returns an array from a json get parameter 
$priceMatrix = GET('prices', 'json'); 

的情況下,值驗證實際上是有意義的,因爲它可以清楚地確定提供的字符串的轉換是否有意義。它可以做一個明確的和預期的轉換,以便在調用該函數後有一個保證的變量類型。

+0

你用顯式類型給出的例子基本上是內置的分機/過濾器所做的,儘管它的接口非常可怕。 – IMSoP

+0

這個想法是古老的,誤導了。是的,你提出了對給定代碼的一些改進,但即使有了改進,代碼背後的整個想法仍然存在缺陷。唯一正確的答案是不要嘗試這樣的事情。要了解*爲什麼*這個想法是錯誤的,請參閱關於以'沒有這樣的事情'開頭的評論' – Jasper

+0

@賈斯珀OK,謝謝你的評論。我們絕對同意,對輸入值的這種通用驗證不是解決所有問題的免費票據。但我不明白爲什麼這應該意味着這種驗證是無意義的。這是一個無效的結論。在我看來,上面的方法提供了輸入值的基本驗證,有用的顯式類型轉換,使得使用請求參數更加方便,並且沒有負面影響。 – arkascha