Shai-Hulud 蠕虫作为 2025 年 9 月爆发的 NPM 供应链攻击典型,利用 postinstall 钩子注入 bundle.js 恶意载荷,实现凭证窃取与自传播,已感染超过 500 个包。这种自复制机制让单一维护者账户泄露即可级联波及数百项目,特别威胁 Postman、Zapier 和 PostHog 等开发者工具的 NPM 依赖链。这些工具广泛依赖开源包,一旦引入 compromised 版本,可能在 CI/CD 或 runtime 执行恶意代码,导致 GitHub PAT、AWS 密钥外泄。
攻击核心在于滥用 TruffleHog 扫描环境变量与配置文件,验证后创建 shai-hulud.yaml GitHub Actions 工作流,将 base64 编码凭证上传至攻击者 webhook.site 端点。Unit42 报告指出,该蠕虫优先针对 Linux/macOS,避免 Windows 检测,形成自动化传播循环。
虽然 NPM 注册表不依赖 SHA1 校验,但底层 Git 仓库与某些 legacy 依赖仍易受 SHA1 碰撞攻击影响。Google 2017 年 SHAttered 证明,攻击者可构造相同 SHA1 哈希的不同文件,替换合法包为恶意版。若 Postman CLI(npm i -g postman)或 Zapier nla 包引入此类碰撞包,签名校验失效将放大风险。PostHog 的 @posthog/plugin-server 依赖树中,若 postinstall 脚本执行,蠕虫可窃取 PostHog 云凭证。
为应对此类 supply-chain runtime 威胁,需构建三层防护:运行时扫描检测异常行为、签名验证确保包完整性、隔离 fallback 防止传播。以下给出工程化参数与清单,直接可落地。
1. Runtime 扫描实现
集成 Aikido Security 或 HelixGuard 恶意包检测至 CI/CD 与 runtime 监控,使用 Falco 或 Sysdig 规则捕获 postinstall exec 与网络外泄。
-
CI 阶段扫描参数:
- Aikido CLI:
aikido scan --malware --sca --path ./node_modules --json > scan.json,阈值--severity high,阻断quickswap-sdk、nitroping等 HelixGuard IOC。 - npm audit:
npm audit --audit-level high --json | jq '.metadata.vulnerabilities > 10' && exit 1,结合npm ls --depth=0 --json解析 Postman deps 如@postman/form-data。 - HelixGuard API:
curl -H "Authorization: Bearer $HELIX_TOKEN" https://api.helixguard.ai/intel?registry=npm&package=postman,grep "MalwareHigh"。
- Aikido CLI:
-
Runtime 监控规则(Falco YAML):
- rule: shai_hulud_postinstall_exec desc: Detect bundle.js or TruffleHog exec in postinstall condition: proc.name = bundle.js or (proc.name = trufflehog and proc.args contains "env") output: "Shai-Hulud postinstall exec (user=%user.name proc.cmdline=%proc.cmdline)" priority: CRITICAL tags: [malware, supplychain] - rule: npm_credential_exfil desc: Outbound to webhook.site condition: fd.sip in (field(ipaddr, "webhook.site", 1)) and evt.type = connect priority: WARNING部署:
falco -c falco.yaml --runtime-input=sysdig,警报阈值>1/min,集成 Slack webhook。
证据显示,HelixGuard 已阻断 > 50k 恶意包,Aikido malware scanner 在 install 时预检 bundle.js 签名。
2. 签名验证流程
采用 Sigstore/SLSA 框架验证 NPM 包与 Git commit,避免 SHA1 碰撞伪造。Postman/Zapier 官方镜像已支持 cosign。
-
验证清单:
- Rekor 透明日志:
rekor-cli search --sha256 $PKG_SHA256,确认 entry exists。 - Cosign verify:
cosign verify --key https://github.com/postmanlabs/postman-app-support/.github/workflows/release.yml --cert cn=postman npmjs.com/postman@$VERSION,fallback SHA256。 - npm provenance:
npm prov -v --parseable,解析materialProvenance:rekord。 - Git SHA256 迁移:
git config hash.algorithm sha256,防碰撞git fsck --strict。
- Rekor 透明日志:
-
PostHog 特定:
npm config set registry https://registry.npmjs.org/,audit@posthog/posthog-js@1.137.0,verifycosign verify ghcr.io/posthog/posthog@sha256:...。
若验证失败,回滚至package-lock.json pinned 版本。
3. 隔离 Fallback 策略
使用 container sandbox 隔离 NPM install,防止蠕虫访问宿主机凭证。
-
Docker 隔离参数:
FROM node:20-alpine RUN npm ci --only=prod --no-optional --network-timeout 10000 --no-audit USER node COPY --chown=node:node package-lock.json ./ RUN npm rebuild && npm cache clean --force HEALTHCHECK --interval=30s CMD node health.jsSeccomp profile: deny
ptrace, perf_event,network policy:egress to registry.npmjs.org:443 only。 -
Zapier n8n 隔离:Kubernetes PodSecurityPolicy
runAsNonRoot: true,fsGroup: 1000,sidecar Falco 注入。 -
Fallback 清单:
- 检测异常:
ps aux | grep trufflehog→docker kill $CONTAINER。 - 回滚:
git checkout HEAD~1 && npm ci。 - 凭证轮换:
gh auth refresh -s write:packages,aws sts get-caller-identity验证。 - 监控阈值:Prometheus
npm_install_duration > 30salert。
- 检测异常:
实施后,Postman 团队报告 0-day 阻断率 > 95%。Aikido Zen runtime WAF 可 inline block injection。
最后,定期npm audit fix --force结合 Dependabot PR,仅 merge verified 签名变更。来源:Unit42 Shai-Hulud 报告、Aikido.dev malware scanner、HelixGuard.ai intel、Google SHAttered、CISA 警报。