最近的Log4j安全漏洞是零日攻击的一个极端例子(但不幸的是,这不是唯一的),整个计算世界都措手不及。
Log4j问题之所以如此有害,是因为Log4j框架被广泛使用,而且暴露的时间太长了。对于编程语言来说,拥有广泛的受信任组件库是一件非常好的事情,Log4j正是这样的例子。虽然它不是Java本身的一部分,但它是用Java编写的,并且是广泛使用的Apache Commons框架的一部分。
这篇文章不会描述这个安全漏洞的细节,而是将使用Log4j作为一个案例来研究管理第三方软件组件的包含版本是如何经常将开发人员置于无赢的情况下的:如果他们升级就糟了,如果他们不升级就糟了。
Log4j问题的主要CVE描述(CVE-2021-44832)描述如下:
“Apache Log4j2版本2.0-beta7到2.17.0(不包括安全补丁版本2.3.2和2.12.4)很容易受到远程代码执行(RCE)攻击,当配置使用JDBC Appender和JNDI LDAP数据源URI时,攻击者控制了目标LDAP服务器。通过将JNDI数据源名称限制为Log4j2版本2.17.1、2.12.4和2.3.2中的java协议,可以解决这个问题。”
我发现以表格形式回顾Log4j发行版有助于更好地理解这一曝光时间长度和版本数量:2013年6月到2021年12月是8.5年,*很多*的版本。
https://logging.apache.org/log4j/2.x/changes-report.html
(截至2021年1月3日)
版本 |
日期 |
评论 |
2021-12-27 |
GA版本2.17.1(安全漏洞固定) |
|
2021-12-17 |
GA版本2.17.0 |
|
2021-12-13 |
GA版本2.16.0 |
|
2021-12-06 |
GA版本2.15.0 |
|
2021-03-06 |
GA版本2.14.1 |
|
2020-11-06 |
GA版本2.14.0 |
|
2020-05-10 |
GA版本2.13.3 |
|
2020-04-23 |
GA版本2.13.2 |
|
2020-02-25 |
GA版本2.13.1 |
|
2019-12-11 |
GA版本2.13.0 |
|
2019-08-06 |
GA版本2.12.1 |
|
2019-06-23 |
GA版本2.12.0 |
|
2019-02-04 |
GA版本2.11.2 |
|
2018-07-22 |
GA版本2.11.1 |
|
2018-03-11 |
GA版本2.11.0 |
|
2017-11-18 |
GA版本2.10.0 |
|
2017-09-17 |
GA 2.9.1版本 |
|
2017-08-26 |
GA版本2.9.0 |
|
2017-04-02 |
GA版本2.8.2 |
|
2017-02-26 |
GA版本2.8.1发布 |
|
2017-01-21 |
GA版本2.8 |
|
2016-10-02 |
GA版本2.7 |
|
2016-07-05 |
GA版本2.6.2 |
|
2016-06-05 |
GA版本2.6.1 |
|
2016-05-25 |
GA版本2.6 |
|
2015-12-06 |
GA版本2.5 |
|
2015-10-08 |
GA版本2.4.1 |
|
2015-09-20 |
GA版本2.4 |
|
2015-05-09 |
GA版本2.3 |
|
2015-02-22 |
GA版本2.2 |
|
2014-10-19 |
GA版本2.1 |
|
2014-08-16 |
Bug修复和增强 |
|
2014-07-29 |
错误修复 |
|
2014-07-12 |
GA版本 |
|
2014-06-21 |
Bug修复和增强 |
|
2014-02-16 |
Bug修复和增强 |
|
2013-09-14 |
Bug修复和增强 |
|
2013-07-10 |
Bug修复和增强 |
|
2013-06-01 |
Bug修复和增强。(安全缺陷介绍) |
|
2013-05-05 |
Bug修复和增强。 |
|
2013-04-20 |
Bug修复和增强 |
|
2013-01-28 |
Bug修复和增强 |
|
2012-11-11 |
Bug修复和增强 |
|
2012-10-07 |
Bug修复和增强 |
|
2012-09-18 |
Bug修复和增强 |
|
2012-08-24 |
Bug修复和小的增强 |
|
2012-07-29 |
Log4j的重写 |
依赖关系管理框架
有许多利用软件组件的依赖管理框架,Log4j网站有详细的文档,介绍了如何将Log4j与Maven、Ivy、Gradle和SBT等多个框架包含在一起。
https://logging.apache.org/log4j/2.x/maven-artifacts.html
Log4j并不是唯一具有较长的发布历史的,这通常是一个积极的属性,因为所有的软件工作都需要发展以保持可行。不管任何给定的依赖框架所要求的XML和JSON等配置的风格差异,开发人员需要解决的关键问题是为每个组件利用包括哪个版本,以及何时升级。
组件升级:不升级才怪
正如开发人员所知,修复一个特定的版本并坚持使用它有一些好处完全他们从一个组件中得到了什么。
另一方面,从不升级组件版本会产生一些负面后果。对于初学者来说,开发人员没有获得新的功能或bug修复。具有讽刺意味的是,如果开发人员有指定的版本Log4j2.0 -beta6(或之前)坚持这样做,他们就不会受到这种特殊的安全威胁。但这种情况不太可能发生,因为这个短语“GA已经发布了,但我们仍然坚持beta版本。”在大多数组织中,无论框架是什么,都会引起很多人的不满。特别是坚持了几年的测试。
长时间坚持使用一个版本的更大风险是组件的生命周期结束的风险。这实际上发生在Log4j Version 1中。另一个风险是技术上的不兼容,这可能会与旧版本的框架发生冲突。
像日志库这样的组件是一回事,但是像数据库或搜索引擎这样的数据层框架的风险就更高了。在过时多年的数据层框架上运行会带来麻烦,因为它不仅使当前操作的支持变得复杂,而且使升级过程——以及由此产生的数据迁移——变得更加困难。
说到自找麻烦,没有停留在操作系统和其他安全相关补丁的顶部可以说是最重要的。
所以很明显不升级是件坏事,开发人员应该经常升级,对吧?
组件升级:如果你这样做就会被诅咒
可以说有两种主要的组件升级策略:总是获得最新的和有选择性的升级。
得到最新的
大多数依赖管理框架都有“获取最新”的配置模式,要么省略指定的版本,要么允许一系列允许的主版本,然后在可用时自动提取最新的小版本。
“获取最新”方法的一个优点是,在组件功能(耶!)、bug修复(耶!)和新bug(耶!)方面总是最新的。对于Log4j问题,这种方法会不幸地自动处理安全暴露,但随后也会自动处理修复——至少在修复可用时是这样。
这种方法的一个代价是,开发人员必须随时准备打破组件更改,无论更改的形式是什么,从明显的(API或下游库不兼容)到更微妙的(组件不像以前那样工作),并将评估时间构建到他们自己的开发和测试评估中,因为每一个新的组件发布可以重新触发组件评估周期,独立于他们自己项目的发布周期。
但至少有一个会持续升级。
选择升级
选择性升级最困难的部分是确定当因为除了检查和升级组件版本之外,大多数开发人员还有成千上万的事情要做。
我也记不清有多少次听到开发人员说这样的话了“我们需要升级X组件,但营销部门希望我们做Y组件,因为他们说我们不能向客户出售基础设施升级或安全升级。”在这个例子中,竞争的问题Y应该被认为是完全合理和增值的。最根本的问题是一个经常流行的观点,即功能要求存在于一个产品路线图上,而技术需求存在于另一个产品路线图上。但我们永远不清楚谁将负责第二个路线图,因为大多数开发团队都在忙于跟上第一个路线图。大多数组织都没有为这类工作做好预算或计划。的确,一个人通常不能卖“基础设施或安全升级”对客户来说,这并不意味着这些努力是不必要的。这种动态的结果就是争取时间升级任何软件组件变成了一场与利益相关者的优先级战斗,他们通常不关心甚至不知道所讨论的组件。
“获取最新”方法有潜在的缺陷,它没有解决需要更重量级升级过程的组件(例如,数据层组件),但是,及时构建组件升级的期望仍然可以说使开发团队处于比什么都不做要好得多的位置,但这将付出只有更高级的开发组织才愿意付出的代价。但是“Get Latest”仍然会直接进入Log4j的曝光,所以就是这样。
考虑到Log4j、SolarWinds和其他最近备受关注的安全事件,技术团队可能更容易争取时间和资源,以便在未来改进各自组织中的软件组件管理,而非技术领导更容易适应这些问题。希望是可以的,因为没有简单的答案。
最后
感谢所有开源组件开发人员和技术社区(如Apache Software Foundation),因为它们提高了开发人员的生产力。如果每个人都决定编写自己的X版本(其中X是一个很好的理解和普遍使用的(和测试的)框架),那么组织将从Log4j安全暴露中吸取错误的教训,因为他们可能会用一组问题交换另一组问题。
从Log4j事件中可以学到一个软件工程的教训:首先引入安全暴露的功能是否真的有必要(功能膨胀?太复杂了吗?),但我将把这个讨论留给其他人。
相关链接
Log4j CVE:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44832
Log4j CVE Jira:https://issues.apache.org/jira/browse/LOG4J2-3293
Apache Log4j安全概述:https://logging.apache.org/log4j/2.x/security.html
“Anna Karenina on Development”——我写的一篇关于发布速度对软件发展和可行性的重要性的博客://www.eqigeno.com/blogs/blog-cacm/251396-anna-karenina-on-development-methodologies/fulltext
道格·梅尔是onada公司的投资组合架构师。他还创立了克利夫兰大数据聚会在2010年。更多Doug的ACM文章可以在这里找到https://www.linkedin.com/pulse/publications-doug-meil
没有发现记录