关于图片Base64格式上传文件时的漏洞

代码逻辑

今天遇到一个漏洞, 是关于图片上传的, 逻辑代码大概是将图片转化为Base64后上传到服务器.

public function sendCompanyLogo(){
    $imgBase64 = input('post.imgBase64/s','','trim');
    if (preg_match('/^(data:\s*image\/(\w+);base64,)/',$imgBase64,$res)) {
        //获取图片类型
        $type = $res[2];
        //图片保存路径
        $new_file = "upload/";
        if (!file_exists($new_file)) {
            mkdir($new_file,0755,true);
        }
        //图片名字
        $new_file = $new_file.time().'.'.$type;
        if (file_put_contents($new_file,base64_decode(str_replace($res[1],'', $imgBase64)))) {
            // 业务代码
        } else {
            // 上传失败
        }
    }
}

复盘

  • 首先将一个php木马文件转化为base64, 此时会生成一个字符串data:application/octet-stream;base64,xxxxxx, 其中的xxxxxx就是木马文件内容.
  • 将base64字符串替换成data:image/php;base64,xxxxxx.
  • 将此字符串上传后会生成一个php文件

修复代码

是在上传时进行类型检查

if(!in_array(strtolower($type),['jpg','jpeg','png','gif'])){
    // 图片类型错误, 并返回
}

此处评论已关闭