在我寫作本書的時候,http://www.php.cn/列出了共3917個函數,其中包括一些類似函數的語法結構,在此我不准備把它們從函數中區分開來,而是把它當作函數看待。
由於函數數量很大,一一說明它們的正確及安全用法是不太可能的。在此我選出了我認為最需要注意的函數。選擇的標準包括使用的頻繁度、使用時的危險(安全)度及我本人的經驗。
對於每一個列出的函數,我都會提供建議的使用方法。在提出這些方法時,我會把安全性當作重點。請在實際使用時根據你的需求進行相應調整。
當一個函數與另一個有相同的風險時,我會給出參見另一個函數的信息,而不是多餘地再次描述一遍。
B.1. eval( )
eval( )函數用於對一個以PHP語句方式解析字串運作。如:
<?php $name = 'Chris'; $string = 'echo "Hello, $name";'; eval($string); ?>
上例中會把$string當PHP
雖然eval(
)非常有用,但是當使用了被污染資料時會非常危險。例如,在下例中,如果$name是被污染的,攻擊者可以任意執行PHP代碼:
<?php $name = 'Chris'; echo "Hello, $name"; ?>
當你無法確信以PHP方式解釋的字串是否使用被污染資料時,以及在可能的情況下,我推薦你避免使用eval( )。在安全審查和同行評審中,應重點檢查該函數。
B.2. exec( )
第6章已提到,執行shell指令是非常危險的操作,在建構shell指令時使用被污染資料會導致指令注入漏洞。
盡量避免使用shell指令函數,但當你需要用它們時,請確信建構shell指令時只使用過濾及轉義過的資料。
<?php $name = $_GET['name']; eval($name); ?>
B.3.
B.3.
) )函數是我喜歡使用的讀取文件方法之一。它會讀取檔案的每一行作為傳回數組的元素。特別方便的一點是,你不需要提供一個文件句柄-你提供檔名,它會為你做好一切:
<?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); ?>
<?php $contents = file('/tmp/file.txt'); print_r($contents); ?>
Array
(
[0] => This is line one.
[1] => This is line two.
)
<?php
$contents = file('http://example.org/');
print_r($contents);
?>
輸出如下(有刪節):
Array ( [0] => <html> [1] => <head> [2] => <title>Example Web Page</title> [3] => </head> [4] => <body> ... [11] => </body> [12] => </html> )
<?php $tainted = file($_POST['filename']); ?>
如果file()函數呼叫的檔案名稱是由被污染資料建構的,則其內容也應被看成是被污染的。這是因為使用被污染資料建構檔名可能會導致你開啟一個有惡意資料的遠端網站。一旦你把數據保存在一個變量中,危險就大幅增加了:
<?php $str = "abcdef"; $se = "len"; $reg = "/abc/e"; echo preg_replace($reg,"strlen($se)",$str); ?>
$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( )用于对符合正则表达式的字符串进行替换。在某些情况下,使用被污染数据构造正则表达式部分会非常危险,因为它的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安全-函数的内容,更多相关内容请关注PHP中文网(www.php.cn)!