天天看點

Codeigniter檔案上傳類型不比對錯誤

Codeigniter的檔案上傳類友善了我們使用PHP來處理檔案上傳的操作,使用起來非常簡單,如下:

$config['upload_path'] = './uploads/';

$config['allowed_types'] = 'gif|jpg|png';

$config['max_size'] = '100';

$config['max_width']  = '1024';

$config['max_height']  = '768';

$this->load->library('upload', $config);

if ( ! $this->upload->do_upload())

{

$error = array('error' => $this->upload->display_errors());

$this->load->view('upload_form', $error);

}

else

$data = array('upload_data' => $this->upload->data());

$this->load->view('upload_success', $data);

如果隻是處理圖檔類型的檔案,基本上不會遇到這個坑,如果處理到了 excel、zip、rar類型的檔案,你可能就會遇到明明在 allowed_types 中允許的檔案類型,最後收獲了 “The filetype you are attempting to upload is not allowed.”的錯誤,為什麼會這樣呢?

Codeigniter的檔案上傳類型判斷在 is_allowed_filetype 這個函數中處理,造成這個錯誤的主要原因是因為判斷邏輯中有一個 mime 類型判斷的步驟。

什麼是 Mime 呢?

MIME是Multipurpose Internet Mail Extention的縮寫,是描述消息内容類型的網際網路标準。

為什麼需要判斷 Mime?因為如果隻從檔案字尾來判斷檔案類型,是非常危險的。不懷好意的使用者可能會把一個可執行檔案字尾改成圖檔類型,上傳成功後,如果能夠獲得檔案的位址,并且檔案在可執行目錄,就能夠執行動态腳本,還是很危險的。著名的DedeCMS就很多這種漏洞。

針對不同的字尾,Codeigniter會從 config/mimes.php 檔案比對POST過來的資料中的 file_type 屬性,隻有一樣才會校驗通過,否則就會發生檔案類型不比對的錯誤。

找到問題的原因,解決起來就很友善了。我們隻需要在 config/mimes.php 檔案中,添加對應的字尾以及file_type 這樣就能解決這個問題。下面是我為幾種常見檔案增加的配置:

'docx'     =>     array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'),

'xlsx'     =>     array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip'),

'xlsm'     =>     array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','application/vnd.ms-excel.sheet.macroenabled.12', 'application/zip'),

'word'     =>     array('application/msword', 'application/octet-stream'),

'rar'     =>     array('application/octet-stream'),

'zip'     =>  array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/octet-stream'),

補充:我這裡使用的Codeigniter是2.x版本的,至于現在3.x版本中是否還存在這個問題并沒有測試,有遇到的朋友可以分享一下。

參考資料: