函數
在我寫作本書的時候,http://www.php.cn/列出了共3917個函數,其中包括一些類似函數的文法結構,在此我不準備把它們從函數中區分開來,而是把它作為函數看待。
由於函數數量很大,一一說明它們的正確及安全用法是不太可能的。在此我選出了我認為最需要注意的函數。選擇的標準包括使用的頻繁度、使用時的危險(安全)度及我本人的經驗。
對於每一個列出的函數,我都會提供推薦的使用方法。在提出這些方法時,我會把安全作為重點考慮。請在實際使用時根據你的需求進行相應調整。
當一個函數與另一個有相同的風險時,我會給出參見另一個函數的資訊,而不是多餘地再次描述一遍。
B.1. eval( )
eval( )函數用於對一個字串以PHP語句方式解析運行。如:
<?php $name = 'Chris'; $string = 'echo "Hello, $name";'; eval($string); ?>
上例中會把$string作為PHP語句來運行,因此等價於:
<?php $name = 'Chris'; echo "Hello, $name"; ?>
雖然eval()非常有用,但是當使用了被汙染資料時會非常危險。例如,在下例中,如果$name是被汙染的,攻擊者可以任意運行PHP代碼:
<?php $name = $_GET['name']; eval($name); ?>
當你無法確信以PHP方式解釋的字串是否使用被汙染資料時,以及在可能的情況下,我推薦你避免使用eval( )。在安全審查和同行評審中,應重點檢查該函數。
B.2. exec( )
第6章中已提到,執行shell命令是非常危險的操作,在構造shell命令時使用被汙染資料會導致命令注入漏洞。
盡量避免使用shell命令函數,但當你需要用它們時,請確信構造shell命令時只使用過濾及轉義過的資料。
<?php $clean = array(); $shell = array(); /* Filter Input ($command, $argument) */ $shell['command'] =escapeshellcmd($clean['command']); $shell['argument'] =escapeshellarg($clean['argument']); $last = exec("{$shell['command']}{$shell['argument']}", $output, $return); ?>
B.3. file( )
file()函數是我喜歡使用的讀檔案方法之一。它會讀取檔案的每一行作為返回數組的元素。特別方便的一點是,你不需要提供一個檔案控制代碼——你提供檔案名稱,它會為你做好一切:
<?php $contents = file('/tmp/file.txt'); print_r($contents); ?>
如果上面的檔案有兩行,則會產生類似如下的輸出:
Array ( [0] => This is line one. [1] => This is line two. )
使用file()函數不是特別危險,但當你在allow_url_fopen選項開啟的情況下使用時,它就能讀取許多不同類型的資源如一個遠程網站的內容:
<?php $contents = file('http://example.org/'); print_r($contents); ?>
輸出如下 (有刪節):
Array ( [0] => <html> [1] => <head> [2] => <title>Example WebPage</title> [3] => </head> [4] => <body> ... [11] => </body> [12] => </html> )
如果file()函數調用的檔案名稱是由被汙染資料構造的,則其內容也應被看成是被汙染的。這是因為使用被汙染資料構造檔案名稱可能會導致你開啟一個有惡意資料的遠程網站。一旦你把資料儲存在一個變數中,危險就大幅增加了:
<?php $tainted = file($_POST['filename']); ?>
$tainted數組中的每個元素與$_POST['filename']有相同的危險性——它是輸入並必須要進行過濾。
在這裡,其行為有可能是意想不到的——$_POST['filename']的誤用可以改變file()函數的行為,因此它可以指向一個遠端資源而不是本地檔案。
B.4. file_get_contents( )
參見 "file( )."
B.5. fopen( )
參見 "file( )."
B.6. include
如第5章所述,include在組織化與模組化的軟體設計中被普遍使用,是非常有必要的。但是,不正確的使用include會造成一個重大的代碼注入安全性漏洞。
在include語句中只使用已過濾資料是非常有必要的。在安全審查和同行評審中,應重點檢查該函數。
B.7. passthru( )
見"exec( )."
B.8. phpinfo( )
phpinfo( )會輸出有關PHP資訊的頁面——啟動並執行版本號碼,配置資訊等等。由於phpinfo()的輸出提供了非常多的資訊,我建議限制對任何使用該函數的資源的訪問。
如果你使用的第八章中的技巧來保護資料庫驗證資訊,則需要確認訪問者不能看到由phpinfo()形成的輸出資訊,這是由於它會暴露超級全域數組$_SERVER的內容。
B.9. popen( )
參見"exec( )."
B.10. preg_replace( )
preg_replace()用於對符合Regex的字串進行替換。在某些情況下,使用被汙染資料構造Regex部分會非常危險,因為它的e修飾符會導致在替換時把用於替換的參數作為PHP代碼來對待。例如(本例為譯者所加):
<?php$str = "abcdef";$se = "len";$reg = "/abc/e";echo preg_replace($reg,"strlen(\$se)",$str);?>
會輸出如下字串:
3def
當使用了e修飾符,不管是否有意為之,它會帶來與eval()相同的風險。在安全審查和同行評審中,應重點檢查該函數。
B.11. proc_open( )
參見 "exec( )."
B.12. readfile( )
參見 "file( )."
B.13. require
參見 "include."
B.14. shell_exec( )
參見 "exec( )."
B.15. system( )
參見 "exec( )."
以上就是PHP安全-函數的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!