一个客户的网站被挂了马,查到最后是上传功能的问题。表单写着只能传图片,实际上后台只检查了文件后缀,攻击者把一段脚本改名为图片格式传上去,再通过路径访问执行。前后不到十分钟,一个后门就进去了。
后缀检查等于没检查
改个文件名太容易了。真正要做的校验有三层:一是检查文件的真实类型,读文件头而不是看名字;二是限制允许的类型白名单,只放 jpg、png、pdf 这几种,其余一律拒绝;三是检查文件内容里有没有可疑的脚本片段,图片就按图片解析一遍。
上传目录必须禁止执行
这是最关键的一条,也是最容易被忘的一条。不管校验做得多好,上传目录都不应该能执行脚本。在服务器配置里关掉这个目录的脚本解析权限,就算传上来一个后门,它也跑不起来。这一条是最后一道防线,比任何校验都可靠。
文件名要重写
用户传上来的名字里可能带路径符号、特殊字符,甚至藏了脚本扩展名。统一重写成一串随机字符加正确后缀,原始名字只作为展示用存在数据库里。这一步顺手就做了,能避免很多路径穿越和解析歧义的问题。
图片还可以再过一遍处理。用图像库重新生成缩略图,原始文件不直接对外提供,这样即使原图里藏了东西也被破坏掉了。视频和文档麻烦一些,至少要做到存放在独立域名或者对象存储上,和主站隔离,风险面小很多。
太原不少企业的官网带招聘、投稿、留言上传功能,这些入口都在公网上,都是被扫描的目标。我的建议是上线前找个懂的人把上传功能单独测一遍,几分钟的事,能省掉后面被挂马的麻烦。上传目录禁执行这一条,我们几乎每个项目的上线清单里都写着。
上传功能的常见疑问
一定要对象存储吗
不必须,但对象存储天然不执行脚本,隔离性好,成本也不高,有条件的优先考虑。
已经上线的怎么补
先关掉上传目录的脚本执行权限,这是最有效的临时措施,再做完整校验,不用停机。
允许传 pdf 安全吗
相对安全,但仍要校验真实类型并对上传目录做隔离,pdf 也可能夹带脚本,别直接内嵌展示。
总结:上传口子看着小,一旦被利用就是整站失守。真实类型、白名单、禁执行、重命名,四层叠上去,才算是堵住了。