依赖安全公告提出一个狭窄且可核验的问题:这个仓库实际解析到的依赖版本,是否出现在任何已发布的安全公告中?
该指标占 安全类别的 20%,与占 80% 的 安全态势并列。
该权重是有意保持克制的。对十六个广泛使用的包所做的校准发现,其中十五个完全没有已知公告:维护良好的项目确实不会交付易受攻击的依赖,因此这里的干净结果是常态,而非殊荣。
衡量的是什么:使用者实际安装的内容
对于发布了包的仓库,被评估的集合是该包的运行时依赖闭包——安装它时真正被拉取进来的每一个包,包括直接与传递依赖——由开放索引 deps.dev 解析得出。报告会给出所评估的确切包名与版本。
只有当仓库没有发布任何包时,检视才会退回到仓库自身的依赖图。那是另一回事:它还包含任何安装器都不会下载的开发与测试版本固定。处于该范围的报告会明确说明。
这一区分并非学究之辨。Flask 的依赖图中含有该项目为测试而刻意固定的旧版 Werkzeug 与 Jinja;它们带有公告,而其中没有任何一个会到达安装 Flask 的人。已发布的闭包是六个包,无一受影响。
目前可解析闭包的是 npm、PyPI、crates.io 与 Maven 的包。发布到 Go、NuGet、 RubyGems、Packagist 或 Hex 的仓库,在索引覆盖它们之前按其仓库依赖图评估:这是数据来源的限制,而非对这些生态系统的评判。
数据来源
每次检视都会读取仓库已解析的依赖集合——直接依赖,加上其下的传递闭包—— 来源是托管平台已经根据提交的清单文件与锁文件计算出的依赖图。
该集合与 OSV 比对。OSV 是由开源安全基金会维护的开放公告数据库,将 GitHub 安全公告、PYSEC、RUSTSEC、Go 漏洞数据库等纳入同一套模式之下。OSV 免费、公开且带版本——正是这些属性,使 Scorecard 成为 安全态势站得住脚的基础。
同一次查询也会返回被报告为恶意的包。它们不是漏洞,也不计入此处:它们既没有严重程度,也没有修复版本,而是作为恶意依赖 单独报告与计分。出现在那里的包,不会同时出现在本页的计数中。
报告哪些内容
对每个受影响的包:解析出的版本、属于直接依赖还是间接依赖、其公告中最严重的级别、适用的公告数量、公告标识符,以及——在公告有说明时——问题被修复的版本。
严重程度取自公告数据库自身的标注。没有该标注的记录(在 PYSEC 条目中很常见)会报告为未知,而不是给出一个猜测值。
如何计分
三个组成部分:
| 组成部分 | 权重 |
|---|---|
| 直接依赖不含已知公告 | 35 |
| 间接依赖不含已知公告 | 25 |
| 没有长期未处理的公告 | 40 |
直接依赖的权重高于传递依赖,因为那是项目自己声明的选择;传递依赖是随之而来的。
严重程度采用已发布的 CVSS 基础分,而非粗粒度标签。每个受影响的包按 0–1 的尺度贡献其分值。只有当某条公告未发布 CVSS 向量时,才使用数据库自身的 critical/high/moderate/low 表述。
在前两个组成部分中,单个最严重的发现占主导,其余数量的影响则递减。一个严重级别的依赖会消耗该组成部分约四分之三;八个低危依赖约消耗三分之一。这个次序是有意为之的——一百条琐碎公告并不等同于一条严重公告——而且数量项永远不会把组成部分压到零,因此有 300 项发现的项目仍然低于有 30 项的项目,而不是与之打平。
第三个组成部分问的是另一个问题:修复已经可用多久了?上周才发布的公告击中你,是运气不好;至今仍解析到一年前公告所影响的版本,则是未能跟进依赖。当某个包最早的公告超过 90 天时,它就会计入这里。若没有任何公告带有发布日期,该组成部分将被排除并重新归一化其权重,而不会被假定为干净。
没有已知公告的依赖集合在三个组成部分上均得满分。
覆盖范围会被声明,而非假定
依赖图中的部分条目没有记录版本。没有版本的包无法与版本范围比对,因此会被跳过并计数——每份报告都会说明评估了多少依赖、有多少未能评估。
依赖图不可用或已关闭的仓库不会因此被扣分。该指标将被排除,"安全"类别的其余权重重新归一化,与任何其他不可用输入的处理方式完全一致——参见 健康指数。
这个指标不主张什么
此处的公告只精确表示一件事:依赖图中记录的版本落入某条公告的受影响范围。
它并不表示存在漏洞的代码路径可以从本项目到达,也不表示该项目可被利用。在庞大的传递闭包中,多数公告在具体上下文里并不可利用。
它同样不区分项目交付的内容与它用来构建和测试自身的内容。依赖图包含开发与测试用的版本固定;一个刻意针对旧版本库进行测试的仓库,会在这里显示那个旧版本。直接/间接的划分是目前可用的最接近的替代指标,并会逐条给出,但它终究只是替代指标。
请与信号,而非保证一并阅读:干净的结果不是安全保证,而一项发现是查看的理由,不是判决。
为什么与安全态势分开
Scorecard 自身的漏洞检查查询的正是同一个公告数据库,并且已经计入 安全态势。若在同一指标内再对一个源自 OSV 的信号计分,等于把同一份证据算了两次。
将二者分开,也让它们各自对其不同的粒度保持诚实。安全态势问的是项目是否存在已知的易受攻击依赖——这只是十九项检查中的一项。本指标问的是具体哪些包、严重到什么程度、在哪个版本中被修复:这正是一个答案在可被据以行动之前必须具备的形态。