Pillow字体编译绕过解压炸弹检查:单次请求可分配1.6GB内存致服务拒绝
CVE-2026-54060披露Pillow库FontFile.compile()严重漏洞:处理BDF/PCF字体时绕过解压炸弹检查,攻击者利用256个低像素字形组合成超大位图(最高1.6GB),导致服务拒绝。影响所有Pillow版本,需尽快修复或手动加固。
🔓 High 漏洞利用
Pillow库中BdfFontFile和PcfFontFile的FontFile.compile()方法在组装字型位图时未调用_decompression_bomb_check(),攻击者可通过上传精心构造的BDF/PCF字体文件,利用每个字形像素低于阈值但组合后远超阈值的特点,触发超大内存分配(最高1.6GB),导致服务器拒绝服务(DoS)。该漏洞影响所有依赖Pillow处理字体文件的Web服务和应用。
来源:OSV | 2026-07-20 | 原文链接
🔍 关键发现
- Pillow的FontFile.compile()在创建组合位图时完全跳过了解压炸弹保护检查,而BdfFontFile和PcfFontFile并未通过Image.open()加载,因此标准保护机制对该路径无效。
- 攻击者利用“缓慢累积”技巧:256个字形的每个像素数(700K)均低于解压炸弹警告阈值(89.4M),但组合后可达1.79亿像素(超过错误阈值1.001倍),甚至使用最大字形高度(65535像素)时总像素达134亿,需分配约1.6GB内存。
- 该漏洞影响Pillow 12.2.0及之前所有版本,官方截至2026年6月8日仍未修复,攻击面包括Web字体预览、服务器端字体渲染和字体转图像功能。
⚔️ 攻击链分析
步骤1:攻击者构造恶意BDF或PCF字体文件,包含256个字形,每个字形尺寸为800×875像素(或更大),确保单个字形像素低于解压炸弹阈值。 步骤2:攻击者将字体文件上传至目标服务器,触发BdfFontFile或PcfFontFile解析。 步骤3:当调用to_imagefont()或save()时,FontFile.compile()将256个字形合成为800×224000(或更大)的位图,未进行任何检查,直接分配大块内存。 步骤4:内存耗尽导致服务进程崩溃或拒绝响应,实现DoS。
🚩 失陷指标 (IOC)
恶意BDF字体文件中字形高度(BBY或PIXEL_SIZE)异常大(如65535)的多个条目PCF字体文件中字形位图数据尺寸远大于正常值(单个字形超800×875像素且数量为256个)
🛡️ 缓解建议
- ✅ 临时修复:在FontFile.compile()方法中手动添加Image._decompression_bomb_check((xsize, ysize))调用,或设置Image.MAX_IMAGE_PIXELS为合理限制。
- ✅ 上游补丁:关注Pillow官方修复版本(预计将添加解压炸弹检查),尽快升级至修复版本。
- ✅ 防御措施:对用户上传的字体文件进行尺寸预检,限制单个字形高度和总像素数;在WAF层拦截含有超大尺寸属性的字体文件。
涉及漏洞:["CVE-2026-54060"]
⚠️ 本文仅供安全研究与学习,IOC 信息请勿用于非法目的。
🤖 常见问题解答(FAQ)
❓ 如何检测当前Pillow版本是否受影响?
检查PIL.FontFile.compile()源码,若第80行附近无Image._decompression_bomb_check调用则受影响。也可运行PoC脚本,若combined_size超过阈值却未报错即存在漏洞。
❓ 攻击者需要上传文件还是可以直接构造?
需要上传恶意字体文件,通常通过Web上传功能或直接提供恶意BDF/PCF文件给服务器端字体处理函数。
❓ 该漏洞可否被用于远程代码执行?
不能。漏洞仅导致内存分配过大触发OOM或崩溃,属于拒绝服务,无代码执行或数据泄露风险。