CVSS 3.1 给 Log4Shell 打了 10.0 分。漏洞满分。报告我盯着那个数字看了很久,漏洞心里想的报告不是“哇好严重”,而是漏洞——这个分数其实没什么用。
漏洞评分系统本来是报告为了帮人排优先级。可当一个漏洞拿到 10.0,漏洞它和另一个 9.8 的报告漏洞之间,在实际处置上几乎没有区别。漏洞你都得放下手头的报告事,立刻去修。漏洞CVSS 的报告区分度在高端区间基本失效了。
CVSS 的 Base Score 由几个维度组合而成。攻击向量(AV)、报告攻击复杂度(AC)、漏洞权限要求(PR)、用户交互(UI),这四个衡量“怎么打”;机密性(C)、完整性(I)、可用性(A),这三个衡量“打坏了什么”。
Log4Shell 的向量是 AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H。翻译一下:网络可达、不需要特殊条件、不需要账号、不需要骗人点击、影响范围超出单个组件、机密性完整性可用性全部高危。每一项都踩在最严重的格子上,乘起来就是 10.0。
问题在于,这套算法假设各维度独立且线性叠加。现实中不是这样。一个需要物理接触的漏洞(AV:P)和一个网络可达的漏洞(AV:N),在真实攻击场景中的差距,远不是公式里那几倍系数能体现的。
CVSS 其实有三组分数:Base、Temporal、Environmental。大多数人在安全公告里看到的那个数字,只是 Base Score。它描述的是漏洞的“理论最大危害”,不包含任何你环境里的具体信息。
我见过一个团队,给内部一个不联网的测试环境里的 Apache 漏洞打了 9.8 分,然后连夜加班修。那个环境连外网都不通,攻击向量 AV:N 在这里根本没有意义。如果他们认真算一下 Environmental Score,把机密性/完整性/可用性的实际影响权重调低,分数可能只有 4 分出头。
CVSS 的 Temporal 组里有“利用代码成熟度”(E)这个指标。一个漏洞刚公开、还没有公开 PoC 的时候,E 是 U(Unproven)。等 Metasploit 模块出来了,E 变成 H(High)。这两个状态下的实际风险差距巨大,但 Base Score 纹丝不动。
我自己的做法是:CVSS 分数只用来做初筛。8.0 以上的漏洞,全部拉出来,然后逐个看三件事——这个组件在我环境里跑没跑、能不能从外部触达、有没有可用的缓解措施。
去年有个 9.8 分的 RCE 漏洞,影响一个我们只在内部 CI 流水线里用的工具。那个工具监听 localhost,不对外。CVSS 向量里写着 AV:N,但“网络”指的是攻击者能到达的那个网络。localhost 不算。我们把它排在了两周后的常规更新里,没有半夜爬起来。
反过来,有个 7.5 分的漏洞,影响的是对外暴露的 VPN 网关,而且 PoC 已经公开了。这个我们当天就处理了。7.5 比 9.8 更急,因为环境不同。
CVSS 4.0 在 2023 年 11 月正式发布。新版本引入了“攻击要求”(AT)和“用户交互”的细分,还增加了对安全决策的补充指标。但核心问题还在:它仍然是一个通用评分框架,不包含你环境的任何信息。
我的看法很简单。CVSS 是个有用的参考,但别把它当决策依据。看到 10.0 不用恐慌,看到 5.0 也别直接忽略。把分数和你自己的资产清单、网络拓扑、业务影响放在一起看,才能做出真正合理的判断。
那个 Log4Shell 的 10.0 分,最后真正让我们紧张的,不是分数本身,而是它出现在一个对外服务的 Java 应用里,而且那个应用用的 Log4j 版本正好在受影响范围内。分数只是提醒我去查了这件事。真正做决定的,是查完之后看到的东西。