供应链安全长期以来一直是一场猫鼠游戏,但 Aikido Security 研究人员最近的一项发现表明,老鼠已经找到了变得不可见的方法。在 2026 年 3 月 3 日至 3 月 9 日期间,一场复杂的攻击活动向 GitHub 和其他主要代码库投放了 151 个恶意软件包。与过去依赖用户拼错库名的“拼写纠缠”(typosquatting)攻击不同,这些软件包利用不可见的 Unicode 字符在众目睽睽之下隐藏恶意逻辑。
这种技术代表了攻击者利用开源生态系统中固有信任方式的一次重大演变。通过利用肉眼无法看见、但编译器和解释器却能精确处理的字符,威胁行为者成功绕过了人工代码审查和传统的安全扫描器。
这次攻击的核心在于 Unicode 的复杂性——这是编码几乎所有书写系统字符的国际标准。虽然我们大多数人认为 Unicode 只是表情符号或带重音的字母,但该标准还包括各种“非打印”字符。这些字符包括零宽空格、方向覆盖符以及在屏幕上不占视觉空间的连接符。
当开发人员审查拉取请求(Pull Request)或检查库的源代码时,他们的 IDE 或文本编辑器通常会将这些字符渲染为“无”。然而,对于 Python 解释器或 JavaScript 引擎来说,这些字符是独特的数据点。攻击者可以在字符串或注释中插入恶意负载,这些内容在人类看来是空的,但在代码运行时会执行命令。
例如,攻击者可能会使用“从右向左覆盖”(Right-to-Left Override,U+202E)字符。该字符旨在通过翻转其后文本的方向来支持阿拉伯语或希伯来语等语言。在恶意语境下,它可以使名为 annoying_executable.exe.txt 的文件显示为 annoying_txt.exe,从而诱导用户运行他们认为只是简单文本文件的程序。
近十年来,供应链安全一直集中在“拼写纠缠”和“依赖混淆”上。安全工具被构建用于标记名称类似于 requesst 而非 requests 的软件包。这些工具在模式匹配已知的错误字符串方面表现出色,但在应对“不存在”的事物时却显得力不从心。
许多传统的静态分析安全测试(SAST)工具依赖正则表达式(regex)来查找漏洞。如果正则表达式没有专门配置为查找非打印 Unicode 范围,它就会直接跳过它们。此外,由于这些字符是有效的 Unicode,它们不一定会触发“文件格式错误”警报。代码在语法上保持正确,即使其行为被隐藏了。
为了理解这一新浪潮的严重性,将其与更传统的代码库投毒方法进行比较会很有帮助。
| 攻击方法 | 主要机制 | 对人类的可见性 | 检测难度 |
|---|---|---|---|
| 拼写纠缠 (Typosquatting) | 拼写错误的软件包名称 | 高(如果仔细观察) | 低 |
| 依赖混淆 (Dependency Confusion) | 利用内部名称与公共名称的冲突 | 低 | 中 |
| 不可见 Unicode | 源码中的非打印字符 | 零 | 高 |
| 账户接管 (Account Takeover) | 窃取维护者凭据 | 无 | 极高 |
Aikido Security 识别出的 151 个软件包不仅仅是概念验证;它们是窃取开发人员机器上的环境变量、SSH 密钥和云凭据的活跃尝试。在研究人员标记该活动时,其中一些软件包已经集成到自动化构建流水线中,突显了这些威胁传播的速度。
这次特定活动的显著之处在于在短短六天内发布的软件包数量之大。这表明攻击者方面具有高度的自动化,很可能使用脚本生成流行库的“影子”版本,并将不可见负载注入通用的实用程序函数中。
随着攻击者转向不可见的威胁,开发人员和 DevOps 工程师必须调整其防御态势。仅依靠视觉检查已不再足够。以下是减轻不可见代码注入风险的实际步骤:
package-lock.json、poetry.lock 或 requirements.txt。这可以防止您的构建系统自动拉取依赖项的恶意“最新”版本。这 151 个软件包的发现是一个清醒的提醒:开源供应链是一个拥有不断进化的捕食者的活生生的生态系统。向不可见 Unicode 攻击的转变表明,威胁行为者正从社会工程转向利用人类感知极限的技术混淆。
随着我们步入 2026 年,行业必须转向依赖项的“零信任”模型。我们不能再仅仅因为代码在屏幕上看起来很干净就假设它是安全的。验证必须是算法化的、自动化的,并且足够深入,以看到肉眼无法看到的东西。



