一、漏洞描述
文件上传漏洞通常由于网站对用户上传的文件未经过校验或者校验不严,导致用 户可以上传任意格式、内容的文件,并可以访问到该文件。恶意攻击者可以利用 这个漏洞,上传可以被服务端解析的木马病毒,导致服务器的权限被恶意攻击者 获取。对网站造成极大的危害。
二、问题
3、解决过程
原先的代码如下:(主要是以后缀名来断定文件类型的)
public function uploadResume()
{
$config = array(
'maxSize' => 10240000,
'rootPath' => PUBLIC_PATH . 'data/tmp/',
'exts' => array('docx', 'JPG', 'PDF', 'JPEG', 'doc'),
'saveName' => array('uniqid', ''),
'autoSub' => false
);
$upload_file = new \Think\Upload($config); //实例化上传类
$info = $upload_file->uploadOne($_FILES['excel_file']);
if (!$info) {
$ReturnInfo['msg'] = $upload_file->getError();
$ReturnInfo['state'] = 0;
echo json_encode($ReturnInfo);
exit();
}
$ReturnInfo['msg'] = '上传成功';
$ReturnInfo['url'] = $info['savename'];
$ReturnInfo['state'] = 1;
echo json_encode($ReturnInfo);
}
修改后的代码如下:
public function uploadResume()
{
$mimes_to_exts = [
'JPG' => 'image/jpeg',
'PDF' => 'application/pdf',
'JPEG' => 'image/jpeg',
'DOCX' => 'application/zip',//wps格式文件
'DOC' => 'application/zip'//wps格式文件
];
$config = array(
'maxSize' => 10240000,
'rootPath' => PUBLIC_PATH . 'data/tmp/',
'exts' => array('docx', 'JPG', 'PDF', 'JPEG', 'doc'),
'saveName' => array('uniqid', ''),
'autoSub' => false
);
$upload_file = new \Think\Upload($config); //实例化上传类
$info = $upload_file->uploadOne($_FILES['excel_file']);
if (!$info) {
$ReturnInfo['msg'] = $upload_file->getError();
$ReturnInfo['state'] = 0;
echo json_encode($ReturnInfo);
exit();
}
if ($_FILES['excel_file']['type'] == 'application/msword' || $_FILES['excel_file']['type'] == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {// 文档校验
if ((string)$info['type'] == 'application/msword' || (string)$info['type'] == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {//微软文档
$ReturnInfo['msg'] = '上传成功';
$ReturnInfo['url'] = $info['savename'];
$ReturnInfo['state'] = 1;
echo json_encode($ReturnInfo);
exit();
}
if ($mimes_to_exts[strtoupper($info['ext'])] != $info['type']) {//wps格式的文档
@unlink(PUBLIC_PATH . 'data/tmp/'.$info['savename']);
$ReturnInfo['msg'] = '文件异常或内容为空';
$ReturnInfo['state'] = 0;
echo json_encode($ReturnInfo);
exit();
}
} else {
if ($mimes_to_exts[strtoupper($info['ext'])] != $info['type']) {// 图片校验
@unlink(PUBLIC_PATH . 'data/tmp/'.$info['savename']);
$ReturnInfo['msg'] = '文件异常';
$ReturnInfo['state'] = 0;
echo json_encode($ReturnInfo);
exit();
}
}
$ReturnInfo['msg'] = '上传成功';
$ReturnInfo['url'] = $info['savename'];
$ReturnInfo['state'] = 1;
echo json_encode($ReturnInfo);
}
这里不仅校验了文件的后缀名,还校验的文件的mime类型,防止文件后缀名一样但文件内容可能不是该类型。这里有一个坑(如果是wps修改过的或新建的文档,浏览器识别的是微软word类型的文档,php识别一个压缩文件,不会带application/msword
、application/vnd.openxmlformats-officedocument.wordprocessingml.document
,这两种格式的。我想wps这样设计,应该是处于版权的考虑吧!)
最后想说,技术虽老,但是处理方法可做参考。如果错误,欢迎指正。