萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP文件上傳一些小收獲

PHP文件上傳一些小收獲

又碼了一個周末的代碼,這次在做一些關於文件上傳的東西。(PHP UPLOAD)小有收獲項目是一個BT種子列表,用戶有權限上傳自己的種子,然後配合BT TRACK服務器把種子的信息寫出來。


開始覺得這玩意很簡單,結果嘛慘不忍睹。用CodeIgniter的上傳類來上傳文件,一開始進展蠻順利的,但發覺走到上傳文件類型的時候就走不下去了。我明明添加了.torrent類型為可上傳類型,結果無論我怎麼傳也傳不上去,還提示我上傳文件類型不對。汗森了,這可是貨真價實的種子文件啊,難道CI只認可島國的種子嗎?

 
打開CI的上傳類看代碼,原來CI的UPLOAD是通過判斷文件的來實現文件識別的。難怪,種子的MIME類型在一般浏覽器上返回的都是二進制數據類型,看來只有自己動手改造一下了。

 
為了盡快完成項目,我直接從控制器(Controller)開始寫代碼。用$_FILE['file']['name']獲取上傳文件的文件名,然後用explode函數來獲取後綴名,最後再調用CI的UPLOAD來上傳文件。代碼如下:

PHP代碼

 代碼如下 復制代碼 $config['upload_path'] = './uploads/';  
$config['allowed_types'] = '*';  
$config['max_size'] = '100';  
$this->load->library('upload',$config);  
$this->load->helper('security');  
$this->load->helper('date');  
$this->load->helper('url');  
$this->load->model('bt_model','',TRUE);  
$data['source_url'] = base_url().'source';  
$data['base_url'] = base_url();  
  
  
  
$file = $_FILES['upload_file']['name'];  
$file_1 = explode('.',$file);  
$file_2 = $file_1[count($file_1)-1];  
if($file_2 <> 'torrent'){  
    echo '<script>alert("只能上傳類型為torrent的種子文件");</script>';  
    echo '<script>window.location.href="'.$data['base_url'].'index.php/index/post";</script>';  
    return;  
}  
$data['type'] = xss_clean($this->input->post('type'));  
$data['name'] = xss_clean($this->input->post('name'));  
$data['space'] = xss_clean($this->input->post('space'));  
$data['username'] = xss_clean($this->input->post('username'));  
$data['time'] = mdate('%Y-%m-%d %G:%i',gmt_to_local(time(),'UP8'));  
if($data['type'] == '' || $data['name'] == '' || $data['space'] == '' || $data['username'] == ''){  
    echo '<script>alert("信息填寫不完整,請重新填寫");</script>';  
    echo '<script>window.location.href="'.$data['base_url'].'index.php/index/post";</script>';  
    return;  
}  
$this->upload->do_upload('upload_file');  
echo $this->upload->display_errors();  
$file = $this->upload->data();  
$data['url'] = $data['base_url'].'uploads/'.$file['file_name'];  
$this->bt_model->insert($data);  
echo '<script>alert("上傳成功");</script>';  
echo '<script>window.location.href="'.$data['base_url'].'";</script>';  

原理大致是這樣的,獲取上傳文件的文件名,然後通過explode()函數來分割文件名以獲取後綴,得到後綴之後與允許上傳類型做比較,最後上傳。

 
講到上傳,我又想到了原來那個特別流行的MIME上傳漏洞。很簡單,當網站判斷上傳文件類型時只判斷MIME類型那麼就會造成上傳漏洞。因為上傳時服務器得到的MIME類型是從客戶端發過來的,也就是說MIME類型的值是可以被用戶控制的,攻擊者克構造虛假的MIME類型來上傳webshell。

所以判斷文件類型的時候還是檢測文件後綴名吧,最好只給上傳目錄一個可讀權限,關閉執行權限,這樣比較靠譜。

copyright © 萬盛學電腦網 all rights reserved