生命周期只有 26 小时的项目

0 阅读3分钟

4 月 1 日 21:59,safe-npx 项目启动。

4 月 3 日 00:45,我决定归档这个项目。

生命周期:大约 26 小时。

起因

2026 年 3 月 30 日深夜,知名 HTTP 请求库 Axios 遭到供应链投毒攻击。

攻击者在两个新版本中注入了一个首次出现的恶意依赖包,植入了跨平台远程访问木马。

npm 在攻击版本发布后约 3 小时 19 分钟将其删除。普遍建议是立即回滚到 v1.14.0。

但即使攻击窗口只有 3 小时,考虑到 Axios 每周下载量超 3 亿次,潜在影响的项目可能数以万计。

我在想:如果能阻止开发者安装这 3 小时内发布的新版本,能不能减少伤害?

通过搜索,我找到了 safe-npm 这个项目,使用非常简单,safe-npm install --min-age-days 120 就能阻止安装发布不满 120 天的包。

过去几年,我们经常听到某知名包的漏洞在发布不久就被曝光。有不足 24 小时的,1 天的,3 天的——社区的响应速度很快。

换句话说,使用发布时间作为防护供应链攻击的检测手段,的确有意义。

这里我犯了一个错误:草率搜索后,就认为尽管有 safe-npm 但没有 safe-npx。

snpx

我开始写 snpx,用于拦截 npx pkg@latest 调用的工具(在 MCP 满天飞的时代,这很有用)。它会检查 latest 版本的发布时间,如果小于 24 小时,就回退到上一个版本。

我想像中的使用场景和 safe-npm 一样简单:

snpx some-mcp@latest

很多时候需要运行脚本时,会直接配置 npx some-mcp@latest 来获取最新功能。这里有一个假设:新版本会修复旧版本的漏洞,所以要比旧版本更安全。

类似 Axios 事件发生,一旦攻击者发布了受污染的新版本,用户会在执行 npx some-mcp@latest 时立刻中招。snpx 的作用就是默认忽略发布不满 24 小时的版本,回退到上一个版本,这一过程是透明的。

价值危机

代码、README、博客……借助代理的力量,几乎所有内容都在字面意义上的瞬间完成。但在我准备开始推广时,发现了问题。

npm 在 2026 年 2 月合并了 min-release-age 功能。

要解决问题的和 snpx 是一样的,为使用基于时间成熟度的安全策略提供了一个快速入口:

npm install -g npm@latest echo min-release-age=7 >> ~/.npmrc

只要你的 npm >= 11.10.0,设置后,所有 npm install 和 npx 调用都会检查包的发布时间。如果发布日期太新直接拒绝安装。

一些思考

简单思索后,我决定在 README 引导用户安装 npm@latest,同时归档 snpx。

这便是 snpx 的困境:平台能力层的扩展吞并了部分工具层。我并不是说工具层在将来会变得一无是处,相反,微型工具将会借助代理的无码力量形成新的价值胶水层。只是怪我启动项目时没有做更全的调查。

不过好在我的情报质量要比调查质量更高,不然很可能老老实实把 snpx 做得更完整了问题才暴露。

突然很怀念以前简单做个组件库就能坐下来安静敲一个月代码的日子。如今这个实现变得和想法一样廉价的年头,编程的乐趣从单纯的代码实现转变成了另一种不可名状的东西。我对此喜忧参半。技术人还能死死抓住的是什么呢?