跳转到内容
Guide

Axios 被后门:5 个 npm 包被 HTTP API 替换

| 9 min read

一名与朝鲜有关联的演员每周向 7000 万安装者发送了 axios 1.14.1 内的 RAT。 您现在可以删除五个单一用途的 npm 包并用 HTTP API 调用替换。

Server room with network cables representing supply chain infrastructure
Photo by Taylor Vick on Unsplash

2026 年 3 月 31 日,一家与朝鲜有关联的运营商发布了两个后门版本 axios 到 npm。 版本 1.14.1 和 0.30.4 附带名为的安装后依赖项 plain-crypto-js 从中提取了特定于平台的 RAT 植入 sfrclak[.]com:8000。 包裹的存活时间为三个小时。 Axios 获得 7000 万 每周下载量。 算一下。

每个运行的 CI 作业 npm install 在该窗口期间将有效负载发送到其构建中 环境。 环境变量中的秘密被泄露; 私人 GitHub 代币已习惯 薄荷后续版本; 开发人员笔记本电脑运行 npm install 本地有一个RAT。 该事件绕过了 2FA,因为维护人员的机器已经通过 有针对性的社会工程活动。 当攻击者拥有时,npm 帐户上的 2FA 不会执行任何操作 运行的终端 npm publish

你无法消除此类攻击,但可以缩小爆炸半径。 每个 npm 包 做一件小事; 验证电子邮件、解析电话号码、剥离 HTML、生成 二维码,签署 JWT; 是一个包,您可以删除并替换为对您的 API 的 HTTPS 调用 通过旋转键控制。 在您做出反应之前,受损的软件包就会运行。 API 密钥遭到泄露 几秒钟后停止工作。

您本周可以使用执行相同操作的 HTTP API 替换以下 5 个 npm 软件包, 加上一个 CI 防护,可以阻止新的安装后挂钩进入您的锁定文件。

审核您当前的 npm 依赖面

在删除任何内容之前,请先了解您拥有什么。 此 shell 传递显示了生产依赖关系 使用安装挂钩并检查中毒的 axios 版本是否位于树中的任何位置:

如果任一 axios 版本出现在您的锁定文件中,请轮换受影响机器或 CI 的每个秘密 工作有机会接触到。 不是“检查日志”。 旋转。 假设渗漏发生在 180 分钟内 发布和删除之间。 泄露的秘密是无法泄露的。

Google Threat Intelligence 将此次操作归咎于 UNC1069,该操作者与执行此操作的是同一人 早些时候 WAVESHAPER 活动。 他们的剧本针对维护笔记本电脑 网络钓鱼,然后利用维护者的凭据进行发布。 你的辩护必须假设 至少一个传递性 dep 的至少一名维护者距离成为植入物仅一步之遥 输送系统。

替换 1:电子邮件验证器➡️ /v1/电子邮件/验证

validator, email-validator, deep-email-validator, 和 disposable-email-domains 出现在注册流程中的很大一部分。 他们一起添加 大约半兆字节的安装重量、它们自己的传递树以及维护的列表 几周内就会过时的一次性域名。

该 API 在一次调用中检查语法、DNS MX 记录和实时一次性域列表。 交换 两个包看起来像这样:

您将失去离线验证的能力。 您获得维护的 MX 检查、实时一次性列表、 以及树中带有安装后挂钩的零软件包。 用于注册、结帐和 Webhook 电子邮件字段,这种权衡有利于 API。

替换2:libphonenumber-js → /v1/电话

libphonenumber-js 是 Google 的一个端口 libphonenumber。 重 147 KB 缩小。 “迷你”版本下降至 79 KB,但丢失了大多数国家/地区的元数据。 完整的元数据 捆绑包使解压后的重量恢复到 2 MB。 在 Cloudflare Workers 或冷 Lambda 上,这是 您每次调用时所付出的实际延迟。

一个 POST 返回 E.164 格式、国家/地区、国家号码、线路类型和时区。 如果数量 无效, data.validfalse 其余的都是空的。 你的服务器端 注册流程将其称为“读取表单”和“写入数据库”。 60 毫秒的 API 往返时间 在现有的数据库写入窗口内。

替换3:二维码→ /v1/qr/生成

qrcode npm 包本身很好:34 KB,没有安装后挂钩。 不好的是 的 canvas 一半的教程都在推动你走向同伴依赖,其中包括 本机代码,安装node-gyp,并在其构建工具链中拥有十年的CVE。 每个土生土长的 npm dep 是一个供应链接缝。

响应是原始 SVG。 将其通过管道传输到文件、将其填充到发票模板中或内联渲染 在 React 组件中 dangerouslySetInnerHTML。 没有本机模块,没有构建 工具链,没有传递树。

替换4:jsonwebtoken→ /v1/jwt/生成和/v1/jwt/解码

jsonwebtoken 是 Node.js 中复制最多的 JWT 库之一。 这也是图书馆 大多数人配置错误:算法错误、缺少观众声明、没有到期日。 错误的算法 verify 调用加上攻击者控制的标头重新引入了 2015 时代的 JWT none 脆弱性。 API 强制执行算法白名单并拒绝端点处的未签名令牌:

将此用于后端服务颁发的短期令牌:密码重置链接,一次性 下载 URL、服务到服务承载令牌。 不要使用外部服务进行用户会话 每个经过身份验证的请求的热路径上的 JWT; 对于这些,请保留一个经过验证的库 并锁定算法。

替换5:html-to-text → /v1/html 到文本/转换

html-to-text, sanitize-html, node-html-parser,以及他们的 朋友的存在是因为每个接受用户内容的 API 最终都需要将 HTML 剥离为纯文本 预览、电子邮件摘要或搜索索引。 它们的总大小为 500 KB 到 1.2 MB; 他们拉 parse5 或者 htmlparser2 穿过门,每个门都有自己的 维护者表面。

为了获得更丰富的输出, /v1/html-to-markdown 返回 GitHub 风格的 Markdown,并且 /v1/html-sanitize 返回带有可配置白名单的已清理 HTML。 选择一个 这与下游消费者想要存储内容的方式相匹配。

添加一个 CI 防护来阻止新的安装后挂钩

删除包是一次性的工作。 保持精益是持续的。 此 GitHub Actions 检查失败 PR 如果锁定文件更新引入了新的 postinstall 或者 preinstall 挂钩树中的任意位置:

该检查很便宜,在每个 PR 上运行,并在任何新脚本钩子落地之前强制进行人工审查。 与它配对 npm config set ignore-scripts true 关于 CI 和明确的许可名单 您知道需要的软件包 esbuild-风格的安装后(TypeScript、Puppeteer、bcrypt)。

你放弃了什么,什么时候放回去

将验证转移到 HTTP 调用会产生实际成本。 你正在用它们换取较小的依赖 表面:

权衡 npm 包 HTTP API
延迟 微秒 距边缘 50 至 150 毫秒
离线使用 是的
安装风险 安装后运行任意代码 无安装步骤
撤销 重建、重新发布、重新部署 在几秒钟内轮换 API 密钥
审计追踪 默认无 每次调用请求日志
版本漂移 固定或翻新 版本头,稳定合约

正确答案是“两者都有,都是有意的”。 保持关键路径库处于进程中(会话 JWT 验证、加密原语、身份验证中间件)。 移动单一用途公用事业的长尾 从您的锁定文件中转移到您可以撤销的签名 HTTPS 端点上。

要点

  • 假设维护者距离植入物仅一步之遥。 Axios 每周获得 70M 下载,但其 npm 帐户仍然因社交工程攻击而受到损害 个人笔记本电脑。
  • 今天审核安装后挂钩。 任何在期间运行任意代码的 dep npm install 是一个供应链接缝。 清点它们,然后删除或列入白名单。
  • 首先删除单一用途的包。 电子邮件、电话、QR、JWT 签名、HTML 转换; 每个都有一个带有可撤销密钥的单行 HTTP 替换。
  • 暴露后旋转,不要调查。 如果有毒的 axios 落在你的 树,轮换受影响环境触及的每个秘密。 渗漏在几分钟内发生。
  • 添加 CI 守卫。 阻止新的 postinstall 钩子不会落在你的 无需人工审核的锁定文件。 axios 的妥协会绊倒这个守卫。

Botoi 为上述 5 个包以及大约 145 个单一用途包提供 HTTP 替代品 实用程序:哈希、UUID 生成、正则表达式测试、时间戳转换、JSON 模式验证、 条形码生成、PDF 渲染等等。 一个 API 密钥,免费套餐上每分钟 5 个请求,无 安装挂钩。 浏览 交互式文档 或接线 MCP服务器 进入你的 AI 编码代理无需离开编辑器即可从 Claude Code 或 Cursor 调用相同的端点。

FAQ

2026 年 3 月 axios npm 包发生了什么?
在 2026 年 3 月 31 日 00:21 至 03:20 UTC 之间,攻击者使用受损的维护者帐户发布了 axios 1.14.1 和 0.30.4,其中包含名为 plain-crypto-js 的恶意安装后依赖项。 该依赖项从 sfrclak[.]com:8000 下载特定于平台的 RAT 植入程序。 谷歌威胁情报将此次行动归咎于与朝鲜有联系的 UNC1069。 这些包的存活时间大约为三个小时,足以存放在全球的 CI 缓存和开发人员笔记本电脑中。
用 HTTP API 替换 npm 包是否会降低风险?
它以两种方式缩小攻击面。 首先,删除在构建服务器上运行任意代码的安装后挂钩。 其次,您将验证逻辑从开发人员笔记本电脑移至通过 API 密钥轮换控制的已签名、仅 HTTPS 的端点。 在您做出反应之前,有毒的软件包就已运行; 撤销的 API 密钥会在几秒钟内停止工作。
HTTP 调用比本地 npm 包慢吗?
对于冷请求的单次调用,是的; 从北美客户端到 Cloudflare 边缘的典型 botoi API 延迟为 50 到 150 毫秒。 对于大多数与您已经进行的数据库调用重叠的服务器端流程(注册、结帐、Webhook 处理),它不会增加任何可测量的内容。 对于高吞吐量路径,通过输入哈希缓存响应,以获得与本地包相同的延迟配置文件。
我现在如何审核我的存储库中是否存在有风险的 npm 包?
运行 npmaudit --omit=dev 以显示生产依赖项,然后使用 npm ls 和 npm view {name} 脚本检查带有安装后或预安装挂钩的任何包。 只做一件小事(电子邮件验证、QR 生成、JWT 签名、电话解析、HTML 剥离)的包是迁移到 HTTP 调用的有力候选者。 进行加密或主动获取网络内容的包是最高优先级的审核目标。
如果 HTTP API 提供商而不是 npm 受到威胁怎么办?
爆炸半径更小,检测速度更快。 您可以控制 API 密钥并可以在一次调用中撤销它。 您的提供商通过 HTTPS 公开状态页面、事件 RSS 和签名响应。 与在构建中运行的包相比,检测需要读取传递依赖树中的每个安装后挂钩。 零风险也不是零风险。 一个给你杠杆,另一个则没有。

开始使用 botoi 构建

150+ 个 API 端点,涵盖查询、文本处理、图片生成和开发者工具。免费套餐,无需信用卡。