PHP文件上傳一些小收獲
來源:程序員人生 發布時間:2013-11-24 07:53:25 閱讀次數:3348次
又碼了一個周末的代碼,這次在做一些關于文件上傳的東西,(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.
所以判斷文件類型的時候還是檢測文件后綴名吧,最好只給上傳目錄一個可讀權限,關閉執行權限,這樣比較靠譜.
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈