记一次任意文件上传的安全缺陷

前言

之前在对项目进行安全渗透测试的时候,有发现我们有一个图片上传接口,有暴露出一个 任意文件上传 的安全缺陷问题。 这个是一个高危的漏洞。

后面查了一下代码,发现原来只在前端有对上传的图片进行 图片的后缀名校验, 服务端是没有校验文件类型的。 所以如果是在 postman 中进行上传操作的话(有拿到合法的 session 的情况下), 是可以绕过前端验证,直接上传任意文件的,包括 .php 文件。

任意文件上传漏洞描述

一般情况下文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。

文件上传本身是web中最为常见的一种功能需求,关键是文件上传之后服务器端的处理、解释文件的过程是否安全。

安全建议

  1. 最有效的,将文件上传目录直接设置为不可执行,对于Linux而言,撤销其目录的’x’权限;实际中很多大型网站的上传应用都会放置在独立的存储上(或者云服务存储,比如 aws 的 s3)作为静态文件处理,一是方便使用缓存加速降低能耗,二是杜绝了脚本执行的可能性
  2. 文件类型检查:建议使用白名单方式,结合MIME Type、后缀检查等方式(即只允许允许的文件类型进行上传);此外对于图片的处理可以使用压缩函数 或 resize函数,处理图片的同时破坏其包含的HTML代码
  3. 使用随机数改写文件名和文件路径,使得用户不能轻易访问自己上传的文件
  4. 单独设置文件服务器的域名

修复

修复也比较简单,就是对这张图片进行 resize 一下, 重新 decode 为图片格式即可, 以 golang 为例,代码如下:

1
2
3
4
5
6
7
8
img := bytes.NewReader(*fileInfo.FileBytes)
_, _, err = image.Decode(img)
if err != nil {
log.Errorf("[ServerUploadFileHandle] parse image failed: %v", err)
res.Code = -1
res.Echo(w)
return
}


参考资料: