Pillow 多帧加载器模式切换后复用旧原生存储,MPO 路径可致越界写与命令执行
Pillow 12.3.0 的多帧加载器在帧间切换 mode 时会复用上一帧的原生 ImagingCore 存储,导致越界写与进程崩溃;作者在 PSD、MPO/JPEG、DCX、MIC 四个入口验证了该问题。
为什么值得看:披露者给出可复现的 MPO 上传路径与 10/10 成功标记,说明多帧模式切换导致的越界写可落到命令执行。
Pillow 12.3.0 的多帧加载器在帧间切换 mode 时会复用上一帧的原生 ImagingCore 存储,导致越界写与进程崩溃;作者在 PSD、MPO/JPEG、DCX、MIC 四个入口验证了该问题。
为什么值得看:披露者给出可复现的 MPO 上传路径与 10/10 成功标记,说明多帧模式切换导致的越界写可落到命令执行。
Pillow 的 PDF 追加路径(Image.save(..., format="PDF", append=True))在处理畸形 /Pages 树时会重复展开同一子引用,造成确定性资源耗尽。
Pillow 12.3.0 的 src/_imaging.c 中 xsize += dx 仅校验正向溢出,当 PILfont 字形步进 dx 取 -32768 并重复 65,537 次时触发 C 有符号整数下溢未定义行为。
Pillow 的 TarIO.__init__ 未校验 tar 头 size 字段是否为正,构造 size 为负值的头部会让 seek 回退到自身,形成永不返回的无限循环,进程占用 98%–100% CPU。
GitHub 安全公告指出,Pillow 的 Exif.load() 在剥离 EXIF 数据开头的 Exif\x00\x00 标记时,每轮都会复制剩余数据,而 PNG 的 eXIf 块没有像 tEXt、zTXt、iTXt 那样受 MAX_TEXT_CHUNK 和 MAX_TEXT_MEMORY 限制,因此填充重复标记的 eXIf 块会让解析耗时随块大小平方增长。
GitHub 安全公告披露 Pillow 在 Windows 构建上存在堆越界读问题 GHSA-9v9v-9qvf-h2hj,EMF/WMF 图像尺寸未经范围检查即传入原生 drawwmf 处理程序,分配按截断为 16 位的头字段计算,拷贝却使用完整 32 位尺寸。
为什么值得看:公告给出可运行的 EMF 构造脚本,并指出 Windows 构建下 16 位截断导致堆越界读的具体代码位置。
Pillow 的 JPEG 编码器 ImagingJpegEncode() 在 src/libImaging/JpegEncode.c:330 写 COM 注释前不检查剩余空间,当 65498 字节 ICC profile 恰好填满 65536 字节缓冲区时,注释和整个压缩图像被写到堆缓冲区之外,进程以 SIGSEGV 或 glibc 堆错误终止。
为什么值得看:披露给出可运行的复现脚本与补丁,说明默认保存路径下 ICC 恰好填满缓冲区即触发越界写。
Nodemailer 的 DKIM 签名在展开 RFC 5322 头部续行时,每轮都对不断增长的合并行重新执行 `/^[ \t]/` 正则测试,导致 O(n^2) CPU 开销。
GitHub 安全公告指出,启用 cacheComponents: true 时,若一个 use cache 函数调用另一个读取 root param 的 use cache 函数,且内层调用命中已有缓存条目,外层函数的缓存键会遗漏该 root param,导致同一份响应被复用于所有 root param 值。
为什么值得看:通告说明启用 Cache Components 后嵌套 use cache 函数的缓存键会漏掉 root param,导致跨值内容串用,且无规避方案。
GitHub 安全公告 GHSA-3547-9m27-7rxg 披露 Django REST framework 的 JSONParser 会用客户端在 Content-Type charset 参数中指定的编码解码请求体,攻击者填入 bz2_codec 等字节变换编码即可绕过 Django 的 DATA_UPLOAD_MAX_MEMORY_SIZE 限制。
为什么值得看:公告给出可运行的复现脚本与四组对照,说明默认解析器下小请求体如何放大内存占用。
Django REST framework 的 content negotiation 对每个 Accept token 重复解析且不限制 token 数量与总大小。
为什么值得看:作者给出完整可运行 PoC 与实测耗时,说明默认 gunicorn 双 worker 部署下两个连接即可让服务停摆。
Django REST framework 的 TokenProxy.delete() 调用不抛异常并返回成功,但实际未删除数据库行,令牌仍可继续认证。原因是 TokenProxy 将 pk 覆写为 user_id,删除语句用用户 id 去匹配 40 位 key 列,返回 (0, {'authtoken.TokenProxy': 0})。
为什么值得看:材料给出可运行的复现脚本与对照实验,说明通过 TokenProxy 撤销令牌会静默失效,便于自查撤销逻辑。
Black 捆绑的 GitHub Action 在启用 use_pyproject: true 时会读取 tool.black.required-version 并直接安装该版本,未做校验,攻击者可通过 PR 修改 pyproject.toml 指向恶意仓库,在受害者仓库上下文中执行不可信代码。
ip-address 的 `new Address6()` 与 `Address6.isValid()` 在应用 45 字符长度限制前先用 `/%.*$/` 剥离 zone 标识符,大量 `%` 后接行终止符时正则从每个 `%` 重试,拒绝耗时随长度平方增长。
LiteLLM Python 包 1.107.0 遭供应链攻击,通过 PyPI wheels 和 Docker 镜像分发,投递凭据窃取器与后门;该版本已在 PyPI 隔离,恶意 Docker 镜像已移除。
同一件事,精选收录的是《LiteLLM 发布流水线被入侵,PyPI 与 Docker 镜像被植入窃密恶意代码》
ammonia 存在 mXSS 漏洞:当同时启用 math 与 annotation-xml 标签、但禁用 encoding 属性时,annotation-xml 与其他 MathML/SVG 集成点标签行为不同,命名空间过滤未能正确剥离不兼容标签,攻击者可注入任意 JavaScript。
Exaforce 分析显示攻击者进入环境后 15 分钟内即开始枚举或窃取数据,而本应发现它们的工具未能生效。三类常见模式包括:开发者 OAuth token 被盗后从 GitHub 窃取代码、ClickFix 借 Claude Code 安装指令投递 macOS 窃密程序、以及冒充 IT 的语音钓鱼骗取真实 MFA 认证。
LiteLLM 披露威胁行为者攻破其多项独立安全控制,于 2026 年 10 月 21 日凌晨约 4 点通过被入侵的发布流水线,向 Docker Hub 和 PyPI 推送了含凭据窃取程序与后门的 1.107.0 版本。LiteLLM 怀疑 GitHub Token 从 AI 网关日志中泄露。
同一件事,精选收录的是《LiteLLM 发布流水线被入侵,PyPI 与 Docker 镜像被植入窃密恶意代码》
OpenSSF 恶意包库更新 MAL-2026-18100,记录 npm 包 [email protected] 在 install 脚本中用 curl 将 GITHUB_TOKEN 拼入 webhook.site 地址外传。
OpenSSF 恶意包库新增 npm 包 [email protected] 的恶意报告,标记为 CWE-506 嵌入式恶意代码。
OpenClaw 的浏览器 CDP 发现功能可接受本应被策略阻止的 WebSocket URL,低信任调用方或配置输入路径可借此访问被拦截的网络目标。该问题仅在受影响功能启用且可达时成立,实际影响取决于运营者配置。首个修复稳定版本为 2026.6.6,升级前可将该功能限制为可信运营者或在不需要时禁用。
GitHub 安全公告披露,@vitest/mocker 针对 GHSA-82fw-gwwq-j7x9 的路径穿越修复在 Windows 上可被反斜杠绕过:修复代码用 node:path/posix 拼接攻击者可控的 URL pathname 与 Vite root。
为什么值得看:作者用可运行脚本对比正斜杠与反斜杠两种遍历,说明已修复的路径穿越在 Windows 上仍可绕过。
@vitest/mocker 的 interceptorPlugin 在 Vite 开发服务器 WebSocket 上接受未认证的 mock 注册,并把 mock 的 url 未转义地插入生成的模块源码,能访问开发服务器端口的非浏览器 WebSocket 客户端可让服务器以任意 JavaScript 替换项目模块,并在开发者浏览器中执行。
GitHub 安全公告指出,Vitest 5 在启用 UI(--ui)、Browser Mode 或 api 时,Vite 的 server.fs.deny 未被按预期应用,能访问该服务器的客户端可通过明文 HTTP 读取 .env、私钥与证书、.npmrc、.git 以及 Vitest 的 API token 文件 .vitest-secret-token。
为什么值得看:通告说明了哪些 Vitest 启动方式会暴露文件、哪些不受影响,并给出显式配置 server.fs.deny 的规避写法。
pypdf 存在未校验 JPEG 图像数据加载问题,攻击者可构造 PDF 触发任意图像解析器被调用,需加载声称使用 /DCTDecode 过滤器的图像。未安装可选 Pillow 依赖的用户不受影响,该问题已在 pypdf 6.21.1 中修复,无法升级者可参考 PR #4222 的改动作为规避方案。
研究者披露 Pillow 的 PIL.EpsImagePlugin.Ghostscript() 在构造 Ghostscript 命令行时直接把用户可控的文件名放在 -f 位置,未校验以 - 或 @ 开头的文件名,构成 CWE-88 参数注入。
为什么值得看:研究者公开了 Pillow 调用 Ghostscript 时的参数注入 PoC,并验证可链式执行命令,默认 -dSAFER 配置下同样成立。
Pillow 的 P;2L 和 P;4L 原始解码器在特定宽高下会读取超出传入缓冲区末尾 1 至 3 字节,原因是 ImagingRawDecode 按位深计算行字节数,而 unpackP2L/unpackP4L 按 2 或 4 个位平面各自按字节补齐,两者对一行数据占用字节数的理解不一致。
Pillow 的 ImagingScaleAffine()(src/libImaging/Geometry.c:866)在 calloc 失败时对调用方拥有的输出图像调用 ImagingDelete(),随后 Python 对象析构时再次释放,形成 use-after-free 与双重释放。
GitHub 安全公告 GHSA-j4m9-6w36-pw47 指出,Pillow 在 stroke_width 非零时创建 FreeType stroker,若 FT_Load_Glyph 对某个字形失败,清理路径会对未初始化或已释放的 glyph 指针调用 FT_Done_Glyph,形成无效释放或双重释放。
为什么值得看:公告给出可运行的 fontTools 脚本,复现 Pillow 在描边绘制时对未初始化指针调用 FT_Done_Glyph 的路径。
Pillow 的 Image.merge() 只校验 bands[1:] 的模式与尺寸,当 band 0 是单波段 I 或 F 图像时,其 image8 平面为 NULL,ImagingMerge 在 src/libImaging/Bands.c:302、:311、:321 解引用该空指针导致进程崩溃。
为什么值得看:公告给出可运行的 PoC 与崩溃栈,说明 Image.merge 只校验 band 0 之外的分带,便于确认 Pillow 部署是否受影响。
Pillow 的 ImagingExpand 在 src/libImaging/Filter.c 中复制边缘像素时未检查输入是否为空,对宽度或高度为 0 的图像应用 MedianFilter、MinFilter、MaxFilter 或 RankFilter 会让整个 Python 进程收到 SIGSEGV。
Pillow 12.3.0 及上游 main 分支(ad277e2761b489681e71b51e91367d46b0ceabb9)在保存 GIF 时,`_get_global_header()` 会因超长注释被反复复制,包括从不可信图片继承的注释。
GitHub 安全公告指出 Pillow 的 GifImageFile._seek() 在 src/PIL/GifImagePlugin.py 中用 bytes 拼接累积 GIF 注释,使 Image.open() 耗时随注释数据量呈二次方增长,默认设置下 2 MB 文件约 5 秒、4 MB 约 35 秒、8 MB 约 3 分钟,而同样大小的普通 GIF 不到 1 秒。
为什么值得看:公告给出触发条件与实测耗时数据,并附上把 bytes 拼接改为列表 join 的补丁,便于使用 Pillow 的服务评估上传接口风险。
GitHub 安全公告库披露 Pillow 的 Image.quantize(palette=...) 在调色板为空时会返回 512 字节未初始化的 C 栈内存作为像素值,一个 80 字节的空 PLTE PNG 即可触发,泄露内容包含栈、堆、libc、libpython 与 _imaging 模块地址及栈保护 canary。
GitHub 安全公告库披露 Pillow 的 XbmImagePlugin 存在 ReDoS:构造的 512 字节文件会让 Image.open() 在单核上消耗约 375 秒 CPU 后才抛出 UnidentifiedImageError。
为什么值得看:公告给出了触发条件、耗时实测与正则修复补丁,使用 Pillow 处理用户上传图片的服务可据此判断暴露面。
Pillow 的 PdfParser.get_value() 递归深度保护失效:max_nesting 默认 -1 且每次递归递减,永远不等于 0,嵌套几千层的 PDF 对象即可触发未捕获的 RecursionError。
Pillow 在把多帧图像以 save_all=True 保存为多页 PDF 时,耗时随帧数呈二次方增长,原因是 src/PIL/PdfParser.py 的 PdfParser.next_object_id() 每次调用都重建并扫描已占用的对象 id 集合。
GitHub 安全公告库发布 GHSA-gg2r-wvfm-q9rx,指出 Pillow 的 MSP RLE 解码器把游程数据写入无上限的 io.BytesIO,单次游程可扩张约 85 倍,问题位于 src/PIL/MspImagePlugin.py:144-146。
Pillow 的 PngImageFile._seek() 在处理首个 fcTL 请求 OP_BACKGROUND 时,会先按 IHDR 声明尺寸调用 Image.core.fill 分配并清零整块画布,之后 Image.open() 的 _decompression_bomb_check 才执行。
为什么值得看:材料给出可运行的复现脚本与两份补丁,说明 APNG 在炸弹检查前按声明尺寸分配内存的路径。
Pillow 的 PdfParser.rewrite_pages() 在追加保存 PDF 时沿页面树 /Parent 链向上遍历且不记录已访问节点,333 字节的自引用 PDF 即可让 im.save(fp, "PDF", append=True) 永久挂起并占满一个 CPU 核心。