TT Lab
开始
学习 学习路径 课程

构建是绿灯,可那个库是谁加进来的

六条红线里,今天能修的是哪一条

在 TT Lab 中继续学习

一句话总结

让扫描结果真正有用的不是严重程度,而是两个判定——这个版本是否 真的落入了那个区间,以及有没有可以修复的版本。

为什么需要它

第一次运行漏洞扫描器,会出现几百行红色条目。把这份清单原样发给开发团队, 什么也不会发生。因为发送的人和接收的人都知道,它们不可能全部修复。 于是这份清单留在附件里,下个月再生成一遍, 仍然什么也不会发生。

能减少的地方只有两处。第一是误报。明明用的是已经修复的版本却被扫出来, 只要混进一两条,整份清单的可信度就会崩塌。“上次不是说过不是吗” 只要出现一次,从那以后就没有人会打开它了。第二是有没有可以修复的版本。 如果已经发布了可以升级的版本,今天升级就行;如果还没有,就是写下缓解措施和期限, 然后持续观察。这两者性质完全不同,但只按严重程度一项排序, 就会混到同一个类别里。

工作原理

用机器可读的方式记录漏洞数据的格式是 OSV schema。核心是 affected 数组,其中的 ranges 记录的是版本的时间线。每个 events 条目是四种中的 一种——introduced(从这里引入)、fixed(在这里修复)、 last_affected(确认到这里为止都受影响)、limit(只看到这里)。 文档明确禁止在一个事件对象中放入两种类型, 并写明 events 数组中至少要有一个 introduced (OSV schema)。

在这里,从业者常出错的地方有三处。

경계        구간은 introduced 이상 fixed 미만이다.
            fixed 와 같은 버전은 이미 고쳐진 것이라 걸리면 안 된다.

last_affected  fixed 가 없을 때 쓰는 천장이라 그 값 **자체는 아직 영향받는다.**
            경계의 포함 여부가 fixed 와 반대다. 문서는 가능하면 fixed 를 쓰라고
            강하게 권한다 — last_affected 는 거짓 음성을 만들 여지가 있다.

여러 구간    한 권고에 구간이 둘 이상일 수 있다. 1.x 에서 고쳐지고 2.1 에서 다시
            들어온 경우가 그렇다. 첫 구간만 보고 끝내면 판정이 뒤집힌다.

该代码块中的韩文依次说明:区间是大于等于 introduced 且小于 fixed,与 fixed 相同的版本已经修复,因此不应被命中;last_affected 是没有 fixed 时使用的上限,这个值本身仍然受影响,边界是否包含与 fixed 相反,文档强烈建议尽量使用 fixed,因为 last_affected 可能产生漏报;一条公告可以有多个区间,例如在 1.x 中修复、在 2.1 中再次引入,只看第一个区间就结束,判定就会颠倒。

而且版本比较本身就是一个陷阱。OSV 的 SEMVER 范围类型要求遵循没有前缀 v 的 SemVer 2.0 顺序,但如果按字符串比较,"1.9.0" 会比 "1.10.0" 更大。必须比较的是数值而不是位数。对于生态系统不强制使用 SemVer 的情况,另有 ECOSYSTEM 类型,此时排序规则因生态系统而异。

最后,必须区分它会被发布到哪里。CycloneDX 用组件的 scope 表达这一点,把运行时调用路径不会触及的内容记为 excluded (CycloneDX 1.6 JSON)。即使严重程度相同, 会打进发布制品的内容与在构建机器上就结束的内容,也是两回事。

在现场相遇的样子

最常见的失败是豁免(waiver)变成万能钥匙。起初是“现在修不了, 写下期限先过去”,过了几个月,连有可修复版本的也被豁免放过去了。 那么关卡从那天起就成了摆设。豁免只应给予无法修复的内容, 并且必须同时写明期限、负责人和缓解措施,这一性质才能保持。

第二种是用 date 读取基准日。如果用今天的日期来判定豁免是否过期, 昨天通过的构建今天就会失败。这本身是正确的行为,但在需要可复现的检查中, 必须把基准日作为输入,同样的输入才会得到同样的答案。

第三种是数据悄悄过时。在无法连接互联网的网络中,会把漏洞数据镜像到内部使用, 而如果没有能察觉镜像已停止的装置,扫描就会一直显示绿灯。 分不清是因为没有命中而显示绿灯,还是因为数据是 3 个月前的而显示绿灯。 所以在数据里写下生成时间,并让关卡同时检查这个时间,会更安全。

还有一点——扫描器说“受影响”,和“可被利用”是两回事。 如果我们从未调用过有缺陷的函数,实际风险就很低。用机器可读的方式记录这种区分的格式是 VEX, CycloneDX 允许在 BOM 中同时表达漏洞信息及其可利用性 (CycloneDX 概览)。不过这种判断 需要由人去读代码才能得出,在清单整理好之前就动手,只会白白耗费时间。

下一项实验要做什么

亲手编写版本比较器并让它通过边界值,然后按照 OSV 时间线比对,只挑出真正会被命中的 条目。接着按“有没有可以修复的版本”和“是否会触及用户”两条轴区分, 用程序写出策略关卡,并用代码固定豁免最多能适用到什么程度。