Heim  >  Artikel  >  php教程  >  PHP文件上传一些小收获

PHP文件上传一些小收获

WBOY
WBOYOriginal
2016-05-25 16:48:24873Durchsuche

又码了一个周末的代码,这次在做一些关于文件上传的东西,(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.

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

本文链接:

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

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn