php判斷上傳檔案檔案類型的安全方法

來源:互聯網
上載者:User
在使用 php 進行檔案的上傳和儲存時,很多人都會給檔案進行重名命並儲存到可寫檔案夾下,然後我們在其中一個失誤的地方便是採用上傳檔案的副檔名作為判斷檔案類型的依據。

這樣做其實與後門大開無異,舉一個簡單的例子,通過副檔名判斷一般是字串的截取判斷,或者是使用$_FILE數組判斷,然後如果使用者上傳的檔案名稱為 image.php.png, image.png.php, image.php%****.png 之類的話,判斷就會出錯。

另外,$_FILES['type']可能被篡改。

下面是我判斷檔案名稱的方法:

讀取檔案頭四個位元組作為判斷。

下面直接上代碼

我實現的是僅支援word和pdf檔案,且檔案大小小於512kb:

$tmpname = $_FILES ['userfile'] ['tmp_name'];if(is_uploaded_file($tmpname)) {$mimetype = detectMIME($tmpname);$tuozhanming = getFileExt($filename, $mimetype);if($tuozhanming == "type_error"){echo '僅支援word和pdf檔案,且檔案大小小於512kb:請重試';exit();}}else{$_FILES ['userfile'] ['error'] = 6;}if ($_FILES ['userfile'] ['error'] > 0) {echo 'Problem: ';switch ($_FILES ['userfile'] ['error']) {case 1 :echo '上傳檔案過大:請重試';break;case 2 :echo '上傳檔案過大:請重試';break;case 3 :echo '檔案上傳丟失:請重試';break;case 4 :echo '無檔案被上傳:請重試';break;case 6 :echo '僅支援word和pdf檔案,且檔案大小小於512kb:請重試';break;case 7 :echo '上傳檔案儲存體失敗:請重試';break;}exit ();}//判斷檔案類型//上傳檔案 $_FILES ['userfile'] ['name'] = time () . "." . $tuozhanming;$upfile = '../uploads/' . $_FILES ['userfile'] ['name'];if ( !move_uploaded_file ( $_FILES ['userfile'] ['tmp_name'], $upfile )) {echo 'Problem: 檔案移動失敗';exit ();}}function detectMIME($filename) {$file = fopen ( $filename, "rb" );$finfo = finfo_open ( FILEINFO_MIME );if (! $finfo) {// 直接讀取檔案的前4個位元組,根據寫入程式碼判斷$file = fopen ( $filename, "rb" );$bin = fread ( $file, 4 ); //唯讀檔案頭4位元組fclose ( $file );$strInfo = @unpack ( "C4chars", $bin );//dechex() 函數把十進位轉換為十六進位。$typeCode = dechex ( $strInfo ['chars1'] ) .                             dechex ( $strInfo ['chars2'] ) .                             dechex ( $strInfo ['chars3'] ) .                             dechex ( $strInfo ['chars4'] );$type = '';switch ($typeCode) //寫入程式碼值查表{case "504b34" :$type = 'application/zip; charset=binary';break;case "d0cf11e0" :$type = 'application/vnd.ms-office; charset=binary';break;case "25504446" :$type = 'application/pdf; charset=binary';break;default :$type = 'application/vnd.ms-office; charset=binary';break;}} else {//finfo_file return information of a file$type = finfo_file ( $finfo, $filename );}return $type;function getFileExt($filename, $type) {switch ($type) {case "application/zip; charset=binary" :$extType = "docx";break;case "application/vnd.ms-office; charset=binary" :$extType = "doc";break;case "application/msword; charset=binary" :    $extType = "doc";   break;case "application/pdf; charset=binary" :$extType = "pdf";break;default :$extType = "type_error";break;}return $extType;}
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.