TP5 base64上传文件并效验文件合法性 # 背景 一天突然收到短信。  排查公司17年写的一个老项目,用到了base64上传图片。 贴代码: ```php /** * 上传图片 */ public function uploadImage() { $param = $this->param; $img = $param['imgPath']; $fileName = $param['fileName']; $fileName = explode(".", $fileName); //获取最后一个/后边的字符 $fileName = $fileName[count($fileName) - 1]; if (empty($img)) { return $this->err('参数错误!'); } //匹配出图片的格式 if (preg_match('/^(data:\s*image\/\S+;base64,)/', $img, $result)) { $path = config('app_file_path') . "/upload/supplier/" . date('Ymd') . "/"; if (!file_exists($path)) { //检查是否有该文件夹,如果没有就创建,并给予最高权限 mkdir($path, 0777, true); } $new_file = $path . time() . "." . $fileName; if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $img)))) { $file_path = str_replace(config('app_file_path'), "", $new_file); if ($result !== false) { $backData['url'] = $file_path; return $this->suc($backData, '', config('app_img_root')); } else { return $this->err('服务器繁忙!'); } } else { return $this->err('上传失败!'); } } else { return $this->err('上传失败!'); } } ``` 普通的base64上传,未对图片进行任何的效验,包含大小,mime,后缀,文件合法性都没有,所以导致此次事件的发生。 为了简单,可在上传的文件后使用框架(thinkphp)进行文件效验。 ``` //$new_file = base64存储的路径 $file = (new File($new_file))->setUploadInfo(['name' => $param['fileName']]); $is_check = $file->check(['size' => 2 * 1024 * 1024, 'ext' => 'png,jpg']); if (!$is_check) { $error = $file->getError(); //解除图片的进程占用 unset($file); //如果为非法文件则删除文件 unlink($new_file); return $this->err('非法文件:' . $error); } ``` 经测试,实现非法文件拦截。 