回顾过去的重大事故,不去复现攻击,而是聚焦于对当下你的运维仍然有用的教训。
发生了什么:写入一行日志成了攻击通道
Log4j 是承担日志输出这一极其常见处理的库,在 Java 应用中被非常广泛地使用。问题在于,这个库会把日志所含字符串中的特定写法解释为「引用外部进行解析」的功能,结果导致执行由外部指定的代码。
也就是说,攻击者只需在「会被记入日志的位置」(用户名、HTTP 头等)放入经过构造的字符串,就有可能在服务器端导致代码执行。日志输出这种被动的处理竟然能成为攻击通道,这让很多人大感意外。
为什么难以判断自己是否受影响
许多应用并没有直接引入 Log4j,而是框架或 SDK 在内部使用了它。这就是 传递性依赖(transitive dependency):依赖的依赖,再往下还有依赖。如果手里没有自己的「物料清单」,连是否受影响都无从判断。
最大的问题是不知道自己是否在用
在「不知道是否在用」的状态下,连处置的优先级都无从排定。是否掌握自己的物料清单(SBOM),在很大程度上决定了能多快应对。
时间线
2021-12-09〜10
漏洞被广泛知晓,全世界一齐着手确认「我们是否受影响」。紧随其后
紧急打补丁与临时缓解措施陆续展开。攻击尝试也急剧增多。此后
修补此前修复不足的后续 CVE 接连公布。「修过一次」并没有就此结束。
至今依然有效的教训
拥有 SBOM(物料清单)
把自己的应用在内部使用了什么可视化出来。用 npm ls、锁文件和 SBOM 生成工具掌握实际在运行的依赖。只看「直接引入的东西」是不够的。
用机器监控依赖
在 CVE 公布的那一刻,自动判定是否受影响(Dependabot / osv-scanner)。能连同传递性依赖一起检查,正是机器监控的强项。靠人工检查必然会有遗漏。
加快打补丁的运维
平时就要例行练习「升级、验证、上线」,以便在紧急时刻能迅速完成。也请参阅 依赖跟进的机制。
追踪后续 CVE
Log4Shell 之后,对修复的再修复出现了多次。不要在「修过一次」就收手,要一直追踪后续报道。
接下来阅读
- 术语:什么是 RCE / 什么是 CVE
- 对策:把依赖的机器监控纳入运维
- 事故:放任已知 CVE 导致 1.47 亿人信息泄露的故事
- 事故:Heartbleed——OpenSSL 的重大缺陷
- 框架:Spring Boot 安全(依赖 CVE、Actuator、授权)
来源与确认范围
以下原始资料支持上文的配置、影响范围或应对措施,链接于2026年10月23日确认。请核对资料中的版本和配置条件。清单优先级及经验是本站的整理,不代表全文重新核验或安全保证。