基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
AIHT
内容
精选全部 AI 动态热点榜AI 日报收藏
分类
模型行业编程产品技术观点开源
更多
Agent 接入
返回首页开发者导航
AIHT
精选 / 资讯详情
8.0
热点
AI SCORE
技术实践2026-10-26 14:14

在 CI 安装依赖前拦截供应链风险

dev.to · AI#供应链安全#持续集成#依赖管理
Editor brief · 编辑速览

教程面向 PHP、npm 和 PyPI 构建依赖安全过滤器,在依赖进入构建缓存前结合威胁情报与规则进行检查。内容覆盖清单解析、仿冒包名和依赖混淆检测,以及 CI 集成、测试与生产加固。

文章思维导图
Knowledge map
拖拽缩放
AI deep read

AI 深度解读

依赖安全检查放在安装之后,可能已经晚了一步:恶意包的安装脚本有机会先执行,再等扫描器报警。原文提出把检查前移,在 CI 安装依赖前读取锁文件,结合漏洞情报和本地规则决定是否放行,覆盖 npm、PyPI 和 PHP 的 Composer 生态。

这个方向值得借鉴,但代码不能直接当成生产工具。输入在检测引擎部分截断,前面的解析器和情报查询也存在明显缺口。对前端和全栈团队,更有用的是理解这道检查该放在哪里,以及哪些检测结果还不足以证明依赖安全。

检查前移,关键是赶在安装脚本之前

原文以 2024 年 10 月的「Black October」攻击为切入点,描述攻击者向 npm、PyPI 和 Packagist 发布仿冒内部依赖的恶意包。不过,输入没有提供事件证据或攻击规模,不能据此判断具体影响。

作者的方案是一个独立 Go 二进制,要求 Go 1.22+,可以通过 go version 检查环境。它作为 GitHub Actions 或 GitLab CI 的一个步骤,读取依赖锁文件,并行查询威胁情报,再应用策略;发现违规时,以非零退出码阻断构建。

真正有价值的是执行顺序:先检查,再安装依赖。

如果把过滤器放在 npm ci 之后,它即使成功报警,也没有实现作者要的安装前防护。同样,要兑现「可疑包进入构建缓存前就被拦截」,CI 的缓存恢复和写入顺序也要配合,单靠扫描程序无法保证。

检测分成两路。OSV.dev、npm audit、PyPI Advisories 和 Packagist Security 用于查询已有情报;本地规则则检查内部包名、近似热门包名和可疑安装脚本。前者依赖情报收录,后者依赖规则质量,两者都不能单独证明一个包没有恶意行为。

统一数据结构容易,正确读出依赖才是难点

作者先把不同生态归一成 Lockfile、Package、Finding、Evidence 和 PolicyConfig。包名、版本、下载地址、完整性信息进入统一模型,命中规则后再记录来源、证据与修复建议。

策略通过 FailOnSeverity 决定哪些等级阻断构建,等级包括 CRITICAL、HIGH、MEDIUM、LOW、INFO;还预留了 IgnoreDevDeps、AllowlistPath 和 CustomRulesPath。

解析器接口让新增生态有了固定入口:

type Parser interface {
    Parse(path string) (*model.Lockfile, error)
    Ecosystem() model.Ecosystem
    LockfileNames() []string
}

要关注 Parse 这一行:后面的检测再完整,也只能检查它成功读出的依赖。

原文列出的文件包括:

  • npm 的 package-lock.json、yarn.lock、pnpm-lock.yaml。
  • PyPI 的 poetry.lock、requirements.txt、uv.lock、Pipfile.lock。
  • Composer 的 composer.lock,并区分 packages 与 packages-dev。

但「列出文件名」不等于「已经支持」。Yarn、pnpm、uv 和 Pipfile 的关键实现没有给出;npm 解析器声称兼容 lockfile v1、v2,却直接对 raw["packages"] 做类型断言。字段不存在时,程序会先发生 panic,无法走到预期的 v1 回退逻辑。

Python 部分的问题更直观。注释声称处理 pkg==1.2.3、pkg>=1.2.3 和 pkg @ url,实际只按 == 拆分,其余形式会被跳过。poetry.lock 则先走 YAML 解析,失败后才回退 TOML,这条路径没有展示可靠性验证。

此外,展示的 Package 没有 Ecosystem 字段,后续却多次访问 pkg.Ecosystem;部分文件缺少必要导入,Composer 的匿名结构体类型也存在不匹配。当前代码首先需要修到可编译,再谈覆盖率。

情报加规则能扩大覆盖,也会扩大误报

情报提供者统一实现 Name()、Query()、RateLimit(),便于调度。OSV 使用 https://api.osv.dev/v1/querybatch,HTTP 超时设为 10 秒;npm 提供者设为 15 秒。代码声明的速率分别是每分钟 100、60 次,本地规则为每分钟 10000 次。

这些数字只是配置和接口返回值。原文没有展示限流器,OSV 注释虽然写了每批最多 100 个包,代码也没有实际分批;可选 API key 的更高额度同样没有给出验证依据。

下面这段负责把 OSV 严重性映射到构建策略:

func mapOSVSeverity(sev []struct{Type, Score string}) model.Severity {
    for _, s := range sev {
        if s.Type == "CVSS_V3" {
            switch {
            case s.Score >= "9.0": return model.SeverityCritical
            case s.Score >= "7.0": return model.SeverityHigh
            case s.Score >= "4.0": return model.SeverityMedium
            default: return model.SeverityLow
            }
        }
    }
    return model.SeverityMedium
}

要检查的是 s.Score >= "9.0":这里比较的是字符串,没有解析 CVSS 分数或向量,不能据此可靠分级。查询响应的结构和后续详情获取也需要核对,原文没有展示完整验证。

npm 示例逐包请求 advisory 路径,注释建议生产环境使用 https://registry.npmjs.org/-/npm/v1/security/advisories/bulk。但当前实现没有展示受影响版本匹配,查询失败或返回 404 时还会直接继续。这样得到的「没有发现」,可能只是「没有查成功」。

本地规则也有三处需要分清:

第一,内部包名命中就报 DEP-CONFUSION,等级为 CRITICAL。代码没有核验包是否来自公共仓库,合法私有包也可能触发。依赖混淆要查的是名称与实际来源是否冲突。

第二,拼写仿冒规则把包名与各生态前 10000 个热门包比较,编辑距离不超过 2、包名长度大于 3 就报 HIGH。编辑距离就是把一个名字改成另一个名字需要多少次字符操作。但代码遇到第一个匹配就退出,并没有实现注释所称的「最近匹配」。

第三,可疑脚本规则生成 SUSPICIOUS-SCRIPT,报告里将脚本文本截到 100 个字符,但 isSuspiciousScript 的实现已经截断。锁文件能否提供足够的脚本内容,输入也没有证明。

我的判断

我认可把锁文件检查放到依赖安装之前,也认可让每条告警带上证据。这比安装完成后才发现问题,更符合阻止安装阶段攻击的目标。

但这份输入是一份架构草稿。章节目录出现了测试和生产加固,实际内容没有展开;检测引擎仅剩开头,无法确认并发、去重、错误处理和退出策略如何实现。作者没有给出实测拦截率、误报率、扫描耗时或对照数据,「快」以及检测效果都不能当成经过验证的结论。

相比现有生态工具,自建过滤器的价值主要在跨生态策略、内部仓库约束和统一证据输出。代价是自己维护解析器、API 兼容性和规则误报。普通团队如果只是查已知漏洞,未必值得先重写整套查询逻辑。

IgnoreDevDeps 也不能因为名字里有 Dev 就直接打开。前端构建工具本来就运行在 CI 中,开发依赖同样可能参与攻击。更合理的判断依据是它会在哪里执行、能访问哪些凭据。

能拿来做什么

  • 在前端或 Node 项目中,把锁文件检查安排在 npm ci 之前,并明确检查失败与情报服务不可用时各自如何处理,避免查询失败被当成安全通过。
  • 先支持团队实际使用的一种锁文件,用真实项目核对解析出的依赖;遇到无法识别的版本、依赖形式或来源时,输出明确错误。
  • 对内部 npm 包同时检查名称、scope 和实际下载来源,把 @corp/pkg、私有仓库配置与 ResolvedURL 放在一起判断。
  • 把拼写相似度和脚本模式先作为人工复核线索,保留规则、来源、版本和原始证据,积累误报情况后再决定是否自动阻断。
Original source

本文由 AI 通读原文后重新编写,观点部分为站内判断,细节以原文为准,来源 dev.to · AI,原文版权归原作者所有。

阅读原文
上一篇
从近万条反馈提炼 Claude Code 约束
下一篇
小米开源桌面硬件,可语音调度编程 Agent

资讯速览

dev.to · AI · 2026-10-26 14:14

AI 评分 8.0 / 10

相关标签

#供应链安全#持续集成#依赖管理

继续阅读

  • JetBrains 开源代理 IDE ThinkRail
  • 从近万条反馈提炼 Claude Code 约束
  • 小米开源桌面硬件,可语音调度编程 Agent
  • Kimi K3.1 Pro 上线,长任务编程新增选择
  • 给编程 Agent 一套抑制过度设计的规则