Maison  >  Article  >  php教程  >  PHP文件上传一些小收获

PHP文件上传一些小收获

WBOY
WBOYoriginal
2016-05-25 16:48:24873parcourir

又码了一个周末的代码,这次在做一些关于文件上传的东西,(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 <> &#39;torrent&#39;){    
    echo &#39;<script>alert("只能上传类型为torrent的种子文件");</script>&#39;;    
    echo &#39;<script>window.location.href="&#39;.$data[&#39;base_url&#39;].&#39;index.php/index/post";</script>&#39;;    
    return;    
}    
$data[&#39;type&#39;] = xss_clean($this->input->post(&#39;type&#39;));    
$data[&#39;name&#39;] = xss_clean($this->input->post(&#39;name&#39;));    
$data[&#39;space&#39;] = xss_clean($this->input->post(&#39;space&#39;));    
$data[&#39;username&#39;] = xss_clean($this->input->post(&#39;username&#39;));    
$data[&#39;time&#39;] = mdate(&#39;%Y-%m-%d %G:%i&#39;,gmt_to_local(time(),&#39;UP8&#39;));    
if($data[&#39;type&#39;] == &#39;&#39; || $data[&#39;name&#39;] == &#39;&#39; || $data[&#39;space&#39;] == &#39;&#39; || $data[&#39;username&#39;] == &#39;&#39;){    
    echo &#39;<script>alert("信息填写不完整,请重新填写");</script>&#39;;    
    echo &#39;<script>window.location.href="&#39;.$data[&#39;base_url&#39;].&#39;index.php/index/post";</script>&#39;;    
    return;    
}    
$this->upload->do_upload(&#39;upload_file&#39;);    
echo $this->upload->display_errors();    
$file = $this->upload->data();    
$data[&#39;url&#39;] = $data[&#39;base_url&#39;].&#39;uploads/&#39;.$file[&#39;file_name&#39;];    
$this->bt_model->insert($data);    
echo &#39;<script>alert("上传成功");</script>&#39;;    
echo &#39;<script>window.location.href="&#39;.$data[&#39;base_url&#39;].&#39;";</script>&#39;;

原理大致是这样的,获取上传文件的文件名,然后通过explode()函数来分割文件名以获取后缀,得到后缀之后与允许上传类型做比较,最后上传.

讲到上传,我又想到了原来那个特别流行的MIME上传漏洞.很简单,当网站判断上传文件类型时只判断MIME类型那么就会造成上传漏洞.因为上传时服务器得到的MIME类型是从客户端发过来的,也就是说MIME类型的值是可以被用户控制的,攻击者克构造虚假的MIME类型来上传webshell.

所以判断文件类型的时候还是检测文件后缀名吧,最好只给上传目录一个可读权限,关闭执行权限,这样比较靠谱.

本文链接:

收藏随意^^请保留教程地址.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn