Setuptools 漏洞致 macOS 上敏感文件意外泄露:MANIFEST.in 排除规则被 Unicode 规范化绕过

CVE-2026-59890 披露了 setuptools 在构建 Python 源码分发包时,因未对 MANIFEST.in 排除规则与文件名进行 Unicode 规范化统一,导致 macOS 上非 ASCII 敏感文件被意外打包并上传 PyPI。本文详细分析漏洞成因、攻击链、检测方法与修复建议,帮助 Python 包维护者防范供应链泄露风险。

⛓️ Medium 供应链攻击

Setuptools 在构建源码分发包(sdist)时,由于 MANIFEST.in 中的排除规则与文件系统上的文件名未进行 Unicode 规范化(NFD/NFC)统一,导致在 macOS APFS/HFS+ 上的非 ASCII 文件(如秘密文件、配置文件)可能被错误打包进 .tar.gz 并上传至 PyPI。该漏洞影响使用 setuptools 进行 Python 包分发的维护者,可能造成敏感信息不可逆泄露。

来源:OSV | 2026-07-21 | 原文链接

🔍 关键发现

  • Setuptools 的 FileList 在匹配 MANIFEST.in 排除指令时,对文件名字节序列直接匹配,不做任何 Unicode 规范化处理。
  • 在 macOS APFS/HFS+ 文件系统上,文件名通常以 NFD 形式存储,而 MANIFEST.in 规则多由编辑器保存为 NFC 形式,导致 NFD 文件名无法被 NFC 规则匹配,排除失效。
  • 受影响文件包括全局排除(global-exclude)、递归排除(recursive-exclude)和 prune 指令,纯 ASCII 规则不受影响。

⚔️ 攻击链分析

1. 开发者在 macOS 上创建项目,包含非 ASCII 命名的敏感文件(如密钥、本地配置)。 2. 在 MANIFEST.in 中编写排除规则(如 global-exclude secret_café.txt),但编辑器保存为 NFC 编码。 3. 使用 setuptools 的 `python -m build --sdist` 或 `setup.py sdist` 构建源码分发包时,排除规则因 Unicode 形式不匹配而失效。 4. 敏感文件被包含在 .tar.gz 中,并可能在发布时上传至 PyPI 索引,造成不可逆泄露。

🚩 失陷指标 (IOC)

  • 包含非 ASCII 字符的文件名在 macOS 文件系统上以 NFD 形式存在
  • MANIFEST.in 中排除规则使用 NFC 编码的非 ASCII 字符

🛡️ 缓解建议

  • ✅ 立即升级 setuptools 至包含修复的版本(关注官方补丁发布)。
  • ✅ 在 macOS 上构建前,手动检查并统一项目中非 ASCII 文件名的 Unicode 规范化形式(推荐使用 NFC)。
  • ✅ 在 CI/CD 流程中添加自动化脚本,用 `unicodedata.normalize('NFC', name)` 验证排除规则与文件名的匹配性。

涉及漏洞:["CVE-2026-59890"]


⚠️ 本文仅供安全研究与学习,IOC 信息请勿用于非法目的。

🤖 常见问题解答(FAQ)

❓ 如何检测我的项目是否受此漏洞影响?

在 macOS 上运行 `python -m build --sdist` 后,检查生成的 .tar.gz 中是否包含本应被 MANIFEST.in 排除的非 ASCII 文件。也可手动用 `hexdump` 对比文件名字节(NFC vs NFD)。

❓ 此漏洞会影响所有文件系统吗?

主要影响 macOS 的 APFS 和 HFS+ 文件系统,这些系统存储文件名时默认使用 NFD 规范化。Linux ex4 等通常保持原样,Windows NTFS 也使用不同规范化方式,但实际影响仅限于 macOS 构建环境。

❓ 修复方案为何强调归一化到同一个规范形式?

推荐统一使用 NFC 形式,因为它是常见的输入法默认输出,且与大多数网络协议兼容。在代码中应对 `os.walk` 返回的路径和 MANIFEST.in 模式分别调用 `unicodedata.normalize('NFC', x)` 后再匹配。

[!] CONTACT_CHANNELS

如需商务合作、技术咨询或漏洞反馈,请通过以下离岸节点联系作者。

> PING_AUTHOR (@A1RedTeam)