APM 安全审计清单:上线前必看的 8 条检查
发布前必做的 APM 安全检查清单
如果你在开发开源包,或者通过 npm 分发代码,就等于把代码放在一个高风险的环境里。过去一年里,npm 生态里发生过不少攻击事件,有些手法非常隐蔽,也很危险。“在我机器上能跑”已经不够了,发布前必须做安全检查。
为什么发布前一定要做安全审查
npm 生态既是 JavaScript 的优势,也是最大的风险点。一个包可能被成千上万的应用引用,甚至进入 CI/CD 流程。一旦包被植入恶意代码,后果会非常严重。攻击者不仅会偷数据,还可能在构建环境中长期驻留。
好消息是,大多数攻击都能提前预防。只要养成习惯、用对工具,很多问题都能避免。
目前 npm 包面临的 12 个主要攻击方式
1. 账号被盗后恶意发布
最坏的情况是你的 npm 账号被黑,攻击者用你的账号发布带后门的版本。用户一安装就中招,恶意代码直接进入生产环境。
防范方法:
- npm 账号一定要开 2FA(必须做)
- 用细粒度的 access token 替代主密码
- 敏感包设置发布审批流程
- 经常查看发布日志
2. 安装阶段就能执行代码
npm 支持 preinstall、postinstall 等生命周期脚本。如果攻击者控制了包,就能趁用户安装时执行任意代码,甚至在真正代码加载前就完成攻击。
防御建议:
- 仔细检查 package.json 里的生命周期脚本
- 能不用就尽量不用
- 必须用的话也要保持简单透明
- 优先考虑构建阶段处理
3. 自传播的 npm 蠕虫
有些攻击会在 node_modules 里修改其他包,让恶意代码在依赖树里快速扩散。这就是所谓的“蠕虫”攻击。
保护方法:
- 安装时不要随意修改文件系统
- 不要去碰其他包的代码
- 依赖要尽量隔离
- 定期用 npm audit 和扫描工具检查
4. CI/CD 流程被入侵
你的 CI/CD 里有很多敏感凭证,比如部署 token、GitHub token。一旦攻击者把恶意包塞进构建流程,他们就能拿到这些凭证。
防御措施:
- 每个阶段只给最小权限的凭证
- 定期轮换 token
- 不要把凭证写在 package.json 脚本里
- 考虑用 OpenID Connect 替代传统方式
- 管理好发布权限
5. 通过 Git 直接拉取依赖
有些人直接从 Git 仓库安装依赖,这会绕过 npm 的安全检查。攻击者可以伪造一个恶意分支,让你误安装。
应对方法:
- 优先用 npm 注册表版本,尽量避免 Git 依赖
- 如果必须用 Git 依赖,要锁定 commit hash
- 不要用
latest或未信任分支 - 明确写出为什么需要 Git 依赖
6. 运行时动态加载依赖
有些包会在运行时动态拉取并执行代码。这会让攻击面变得隐形,包本身成了恶意载荷的“加载器”。
最佳实践:
- 所有依赖都要静态声明在 package.json 里
- 不要在运行时动态拉取代码
- 用静态分析工具检查是否有动态 require
- 设计功能时尽量避免代码执行
7. 利用 npm 做网络钓鱼
攻击者可能利用 npm 的 CDN 和托管能力,在包里嵌入钓鱼页面或窃密脚本。表面看起来是正常包,实际却把用户引导到假登录页。
保护用户的方法:
- 明确说明包的功能和用途
- 清楚标出官方域名和文档地址
- 关联网站加上 CSP 头保护
- 监控包名的拼写变体
- 发现可疑包立即上报
8. 窃取环境变量和凭证
攻击者可以在安装时读取 .env 文件、Docker 配置或 CI/CD 环境变量,偷走 API 密钥、token 等敏感信息。
加固建议:
- 不要把密钥提交到版本控制系统
- 使用专业的密钥管理工具
- 遵循最小权限原则
- 审计包会访问哪些环境数据
- 不要记录敏感信息
9. 数据外泄和隐蔽通道
攻击者会用 DNS 查询、图片请求等隐蔽方式,把偷来的数据悄悄送出去。
检测与防御:
- 监控包的对外网络连接
- 用扫描工具在安装前分析包行为
- 实施出站流量控制
- 对外<|eos|>