PHP任意文件下載漏洞是指攻擊者利用程序缺陷,將惡意腳本上傳至服務(wù)器,通過漏洞獲取目標(biāo)服務(wù)器訪問權(quán)限或者竊取敏感信息。
比如,攻擊者可以通過get方式傳遞文件地址參數(shù),然后直接通過文件讀取函數(shù)進(jìn)行下載,如下:
$file = $_GET['file']; header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.basename($file).'"'); header('Content-Length: ' . filesize($file)); readfile($file);
上述代碼中,惡意用戶可以傳遞一個(gè)類似于文件地址參數(shù)“http://xxx.xxx.xxx.xxx/test.php?file=/etc/passwd”,程序并不做過多判斷和限制,即可讓攻擊者下載網(wǎng)站目錄中的任意文件,包括配置文件、日志、數(shù)據(jù)庫等等敏感信息。
因此,開發(fā)人員必須認(rèn)真對(duì)待任意文件下載漏洞,嚴(yán)格限制下載文件的目錄,對(duì)下載的文件進(jìn)行合法性判斷和防范SQL注入等攻擊方式。
一種簡(jiǎn)單的解決方法是根據(jù)白名單限制允許下載的文件類型和目錄,代碼如下:
$file = $_GET['file']; $white_list = array( '/var/www/html/download/', '/var/www/html/images/' ); if (in_array(dirname($file), $white_list) && in_array(pathinfo($file, PATHINFO_EXTENSION), array('pdf', 'doc', 'docx'))) { header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.basename($file).'"'); header('Content-Length: ' . filesize($file)); readfile($file); }else{ die('Sorry, you are not allowed to download this file.'); }
上述代碼中,我們通過白名單方式限制允許下載的文件類型和目錄,同時(shí)使用dirname()獲取文件所在的目錄,pathinfo()獲取文件擴(kuò)展名進(jìn)行驗(yàn)證。
除了白名單方式,還可以通過黑名單方式實(shí)現(xiàn),即排除下載不允許下載的目錄和文件類型,如下:
$file = $_GET['file']; $black_list = array( '/var/www/html/config/', '/etc/' ); if (!in_array(dirname($file), $black_list) && !in_array(pathinfo($file, PATHINFO_EXTENSION), array('php', 'com', 'exe', 'bat'))) { header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.basename($file).'"'); header('Content-Length: ' . filesize($file)); readfile($file); }else{ die('Sorry, you are not allowed to download this file.'); }
上述代碼中,我們通過黑名單方式排除不允許下載的文件類型和目錄,驗(yàn)證方式和白名單方式相反。
總之,在使用文件下載功能時(shí),一定要注意安全,避免出現(xiàn)任意文件下載漏洞,以防被黑客攻擊造成損失。