图片处理库被列为攻击面,站点上传环节该收哪几道门禁
图片处理库被列为攻击面,是因为它在服务端解码用户上传的二进制内容:缩略图、转码、加水印每一次操作都要经过解码器,而历史上多起远程代码执行正是发生在解码这一层,不在业务代码里。同行 CMS 给出的收口思路值得对照——PbootCMS 在 V3.2.22 的更新记录里为 Imagick 做了安全硬化:危险 coder 门禁、输入格式白名单与资源上限三项一起加,同时修复了合法图片误判。站点的上传环节照这个框架收三道门禁即可。
为什么图片处理库会算攻击面
三个条件叠加:输入不受信(任何人可上传文件)、解析成本高(图像解码要分配内存与算力)、格式面广(图像库支持的编码格式远多于业务实际需要)。攻击者的机会在第二个环节——构造畸形文件让解码过程越界,或利用冷门格式的解析缺陷。上传入口看起来最「人畜无害」,恰恰因为它默认被信任:图片嘛,看看总没事。
危险解码器要单独关
图像库内部按格式分模块(coder),冷门格式的模块是事故高发区:图形交换类、历史遗留的矢量与多帧格式、以及会被内部委托机制调起的组件。门禁的做法是显式禁用不需要的模块,只留业务真正支持的编码,而不是保留全量再靠上层过滤。这一步的效果是让「格式面的攻击」根本进不了解码流程,配置一次长期有效。
输入格式按白名单收
第二道门禁看输入声明:上传的文件类型按白名单接受,常见业务只需要三四种图片格式;同时校验实际文件头与声明一致性,不符即拒。白名单比黑名单稳,逻辑和扩展名过滤相同——允许已知,拒绝未知。注意白名单管的是「允许进来什么」, coder 门禁管的是「允许用什么方式解码」,两道各堵一个维度,缺一都有缝。
给解码设资源上限
第三道门禁防成本滥用:限制单帧尺寸与总像素、限制文件大小与内存用量、设置解码超时。没有上限时,一个小文件可以解压出巨幅图像耗尽内存,这就是「解压炸弹」的形态;多帧格式还能把处理时间放大几十倍。上限数值按业务正常图片的分布定,留出余量但不要数量级的余量。同行系统把三项与资源上限并列做进同一次硬化,正是因为缺任何一项,另外两项都会被绕过。
门禁过严会误伤合法图片
三道门禁全拉满的副作用是误判:边缘浏览器生成的非常规图片、超大尺寸摄影原片可能被资源上限拦下,白名单太窄会拒绝业务其实需要的格式。PbootCMS 在同一条记录里专门修了合法图片误判,说明这不是一次配好的事。做法是把拒收做成可观测的:记录被拒文件的原因分布,定期回看,确认是攻击样本还是正常内容,再微调上限与清单。
| 门禁 | 拦什么 | 常见误伤 |
|---|---|---|
| 危险解码模块禁用 | 冷门格式的解析缺陷 | 极少,确认业务格式即可 |
| 输入格式白名单 | 伪装类型的上传 | 过窄清单拒掉合法新格式 |
| 解码资源上限 | 解压炸弹与超大图 | 高分辨率原片被尺寸限制拒收 |
站内侧的对照:AnQiCMS 的标题自动配图由系统按标题分配图片,不在请求路径上引入外部解码组件;部署用宝塔面板或 Docker 镜像时,上传目录与处理组件同样建议按这三道门禁做一次核对。
常见问题
只收 JPG、PNG、WEBP 三种格式够用吗? 多数内容站够用。动图与文档类按需再加,每加一种格式就是多开一条解码通路,能给出业务理由再加。
资源上限设多少合适? 从现网图片的分布倒推:取正常上传图片的最大边与总像素,再放一到两倍余量。按数量级放宽等于没设。
被误判的图片怎么申诉? 不要先放行再补洞:记录样本、分析拒绝原因、调整对应那一道门禁的参数,用日志回看确认新参数不再误伤,这是「可观测拒收」的意义。