文章总结: 2026年5月14日npm仓库发生node-ipc恶意包供应链攻击事件,三个恶意版本通过混淆代码窃取云凭证、SSH密钥等敏感数据。文章分析npm结构性缺陷(默认执行脚本、维护者不活跃、无审核机制)导致此类事件频发,并提供立即排查步骤、检测规则及构建时、运行时、运营时三层防御策略,强调需从根本上解决npm生态安全问题。 综合评分: 88 文章分类: 供应链安全,漏洞分析,恶意软件,安全运营,解决方案
【安全评论】npm 又中招了:”我们无法预防”——唯一经常发生此事的包管理器
原创
Blake Chen Blake Chen
黑白之道
2026年5月18日 08:31 江西
在小说阅读器读本章
去阅读
导语:2026年5月14日,npm 仓库中三个恶意版本的 node-ipc 包被同时发布,意图窃取全球开发者的云凭证、SSH 密钥和 AI 工具配置。这不是 npm 第一次发生这种事,当然也不会是最后一次。每隔几个月,整个 JavaScript 生态就会经历一次这样的”自然灾难”——而官方每次的回应,都是那句令人熟悉的”我们真的无法预防”。
一、事件回顾:一颗定时炸弹如何被引爆
1.1 事件经过
2026年5月14日,npm 账户 atiertant(关联邮箱 [email protected])在同一时刻发布了三个恶意版本的 node-ipc 包:
- [email protected](虚构版本号,9.x 分支此前从未有 CommonJS 构建)
- [email protected](同上)
- [email protected](针对特定目标的高精度攻击版本)
该包每周下载量高达 822,000 次,历史累计下载超过 10,000,000 次。一旦开发者在项目中使用 npm install node-ipc(未锁定版本),恶意代码便会通过 require('node-ipc') 自动加载,无需任何触发条件。
1.2 恶意代码行为分析
恶意 payload 被注入在 node-ipc.cjs 文件末尾(第 1271 行),是一个 80,079 字节的混淆 IIFE(立即执行函数)。payload 执行流程如下:
阶段一:配置解码
// 自定义 Base-16 编码的 C2 配置
// 解码后得到:
r: 'sh.azurestaticprovider.net:443', // C2 地址(伪装成 Azure)
k: 'qZ8pL3vNxR9wKmTyHbVcFgDsJaEoUi', // HMAC 认证密钥
z: 'bt.node.js', // 请求标识符
阶段二:定向指纹(仅 12.0.1)
12.0.1 版本内置了 SHA-256 定向指纹校验,会比对当前模块路径的哈希值。只有匹配预设目标的系统才会执行完整 payload,非目标系统则静默退出。这意味着攻击者已经锁定了特定的开发环境或项目。
阶段三:凭证窃取
payload 会尝试窃取超过 90 类敏感数据,包括:
| 类别 | 目标路径 |
| — | — |
| 云凭证 | ~/.aws/credentials 、~/.azure/accessTokens.json、~/.config/gcloud/credentials.db |
| SSH 密钥 | ~/.ssh/id_rsa 、~/.ssh/id_ed25519、/etc/ssh/ssh_host_*_key |
| AI 工具配置 | ~/.claude.json 、~/.claude/mcp.json、.kiro/settings/mcp.json |
| 基础设施即代码 | ~/.terraform.d/credentials.tfrc.json 、**/terraform.tfvars |
| CI/CD 工作流 | **/.github/workflows/*.yml 、**/.gitlab-ci.yml |
| Shell 历史 | ~/.bash_history 、~/.zsh_history |
阶段四:双通道数据外泄
- HTTPS 外泄:将窃取数据压缩为 gzip,通过 HTTPS POST 上传至
sh.azurestaticprovider.net - DNS TXT 外泄:绕过企业 DNS 监控,直接将数据编码为 DNS 查询发送至 C2 服务器 IP
二、历史重演:npm 为何总是”无法预防”
2.1 这不是第一次
node-ipc 并非首次被滥用。2022年3月,该包的 10.1.1 和 10.1.2 版本曾被用于部署名为 peacenotwar 的恶意负载——在特定地区用户的家目录下创建 USE_PEACE_NOT_WAR 文件夹,并在特定触发条件下删除系统文件。
两次攻击,背后是不同的威胁行为者,却利用了同一个 npm 包生态位。
2.2 npm 的结构性缺陷
讽刺文章的核心论点在于:npm 是唯一一个定期发生此类事件的包管理器。为什么?
问题一:默认执行任意代码
npm 默认会在 npm install 时执行包中的 preinstall、install、postinstall 脚本。这意味着当你执行 npm install foo 时,你实际上是在告诉系统”请下载这个未知来源的代码压缩包,然后以当前用户权限执行其中的任意脚本”。
这在设计上就是一次供应链攻击的完美入口。
问题二:维护者账户长期不活跃
node-ipc 的原作者 Brandon Nozalski Miller(GitHub 用户名 RIAEvangelist)自 2024年8月12日 发布 12.0.0 后便停止维护。21个月后,攻击者获得了维护者权限,发布了三个恶意版本。在 npm 的生态中,高下载量但无人维护的”孤包”是典型的狩猎场。
问题三:版本发布无审核期
当攻击者在同一天、同一时刻发布三个版本覆盖不同 semver 范围时,没有任何机制可以阻止这一切发生——直到安全研究员发现并手动举报。
对比其他生态
讽刺文章指出,在 Go、Rust 等生态中,由于语言自带强标准库和严格的构建工具链,开发者对第三方代码的依赖深度远不及 npm,因此类似事件的频率和影响也低得多。
三、蓝队视角:我们能做什么
3.1 立即排查
如果你的项目使用了 node-ipc,请执行以下命令:
# 检查直接依赖版本
npm ls node-ipc
# 搜索 lockfile 中的受影响版本
grep -E '"node-ipc".*"(9\.1\.6|9\.2\.3|12\.0\.1)"' package-lock.json
# 检查 CI/CD 和开发者机器上的安装历史
npm list node-ipc --all
如果发现存在受影响版本,请立即假设凭证已失陷,执行以下操作:
- 轮换所有在失陷系统上使用过的凭证(AWS密钥、SSH密钥、GitHub Token等)
- 检查 CI/CD 环境的网络外泄日志
- 检查
$TMPDIR/nt-*目录是否存在(payload 临时文件) - 检查环境变量中是否存在
__ntw=1(daemon 进程标记)
3.2 构建检测规则
SIEM 检测示例(Splunk SPL)
# 检测失陷版本安装
index=npm_logs event_type=install (version="9.1.6" OR version="9.2.3" OR version="12.0.1")
| stats count by host, user, version, timestamp
# 检测 C2 域名访问
index=network_logs dest_domain="sh.azurestaticprovider.net" OR dest_ip="37.16.75.69"
| stats count by src_ip, dest, timestamp
# 检测异常 DNS 外泄查询(直接到非标准DNS服务器)
index=dns_logs src_ip!=10.0.0.0/8 query="*.bt.node.js"
| stats count by src_ip, query, timestamp
3.3 长期防御策略
纵深防御三层面
层面一:构建时(Build-time)
- 启用
npm config set ignore-scripts true,禁止自动执行 install 脚本 - 使用
npm ci而非npm install,确保 lockfile 精确匹配 - 部署私有 npm 镜像(如 Verdaccio),所有包经过安全审核后再进入内部生态
- 使用 Socket.dev 或 Snyk 的包分析功能,在安装前评估包的安全风险
层面二:运行时(Runtime)
- 限制 CI/CD 环境的外向网络流量,仅允许必要端点
- 在开发者工作站上启用 EDR 监控 npm 安装行为
- 使用容器化构建环境,确保每次构建在隔离环境中执行
层面三:运营时(Operations)
- 建立 npm 包监控机制,追踪项目依赖的健康状态
- 对高风险包(长期不更新、大量下载、作用域可疑)进行标记
- 将供应链安全纳入漏洞响应流程,设立专门的应急响应通道
四、结语:我们还能说什么
每次 npm 供应链事件发生后,官方都会发表一份声明,表示遗憾,并强调”无法预防”。而社区则会在短暂愤怒后,继续 npm install,继续信任下一个 40 层深的依赖树。
作为蓝队,我们习惯了”假设已被攻破”的思维模式。但在 npm 这里,攻破从未停止——它就是日常。
讽刺文章的最后一句话说得很好:“直到明天早晨的下一场不可避免的灾难,我们必须保持韧性。”
韧性当然重要。但韧性不意味着每次都用临时补丁去修补一个根本不该存在的伤口。
或许,是时候认真讨论一下 npm 的结构性安全问题了。
版权声明:本文由华盟网原创发布,保留所有权利。配图由华盟网授权使用。
👇 点击阅读原文,访问我的网站
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:黑白之道 Blake Chen Blake Chen《【安全评论】npm 又中招了:”我们无法预防”——唯一经常发生此事的包管理器》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论