应对 Log4j 严重漏洞

目录

简介

在流行的 Apache Log4j 日志记录库中发现了一个严重的远程代码执行 (RCE) 漏洞,影响版本 2.0 直到并包括 2.14.1。此漏洞已影响大量基于 JVM 的系统。有关漏洞本身的更多信息,请参阅 CVE-2021-44228

更新(2021 年 12 月 22 日):自第一篇文章发布以来,又发现了两个其他漏洞 - CVE-2021-45046CVE-2021-45105 - 因此请务必查看不同部分以获取更新的说明。

此漏洞正在被积极利用。所有 Gradle 用户都应评估其软件项目是否容易受到攻击,如有必要,尽快更新到 Log4j 2.17.0 或更高版本。我们已在下方提供了有关如何识别和预防项目中此漏洞的说明

我们强烈建议您配置 Gradle 构建,以使用依赖约束拒绝任何有漏洞的 Log4j 版本。

除了项目依赖项之外,我们还建议保护您的构建依赖项,如下所述。

请注意,Gradle 构建工具本身不受此漏洞的影响,因为它不使用 Log4j。Gradle 使用 SLF4J 和自定义日志记录实现,不易受到有漏洞的字符串替换的影响。

Gradle Scala 插件使用 Zinc Scala 编译器,该编译器依赖于有漏洞的 Log4j 版本。但是,在这种情况下,Gradle 也提供了自己的日志记录实现,默认情况下不使用 Log4j。

此帖子的更新

保护您的项目依赖 #

1. 确定您的项目是否使用了有漏洞的 Log4j 版本 #

首先,使用依赖项报告Build Scan™ 验证您的项目是否使用了有漏洞的 Log4j 版本。有关详细信息,请参阅查看和调试依赖项

版本介于 2.0 和 2.16.0(包括两者)之间的所有 org.apache.logging.log4j:log4j-core 版本都容易受到攻击。

2. 将 Log4j 依赖升级到非漏洞版本 #

在每个子项目的构建脚本或版本目录dependencies 块中升级 Log4j 依赖项,如果您使用依赖项的集中声明。

更新(2021 年 12 月 14 日):Log4j 发布了 2.16.0,它禁用并删除了漏洞核心功能的支持。在某些非默认配置中,软件 使用 2.15.0 时仍然可能存在漏洞。为了绝对确定,您应该更新到 2.16.0。以下说明已修改为使用 2.16.0。

更新(2021 年 12 月 22 日):Log4j 发布了 2.17.0,它修复了另一个漏洞。为了绝对确定,您应该更新到 2.17.0。以下说明已修改为使用 2.17.0。

3. 防止意外解析项目中有漏洞的 Log4j 版本 #

鉴于此漏洞的严重性,我们建议采取以下额外步骤,以防止意外包含有漏洞的版本。请注意,即使您没有直接使用 Log4j,也有可能通过您的某个依赖项传递性地解析出有漏洞的版本。

使用依赖项约束功能,以确保您的项目无法解析受影响的 Log4j 版本,方法是将以下代码段添加到您的 Gradle 构建中

dependencies {
    constraints {
        implementation("org.apache.logging.log4j:log4j-core") {
            version {
                strictly("[2.17, 3[")
                prefer("2.17.0")
            }
            because("CVE-2021-44228, CVE-2021-45046, CVE-2021-45105: Log4j vulnerable to remote code execution and other critical security vulnerabilities")
        }
    }
}

除非 log4j-core 出现在依赖项图中,否则约束将不会被激活。约束将强制将依赖项升级到至少 2.17.0,或者在无法满足严格版本约束时使构建失败。

请注意,在此处使用 implementation 配置将涵盖 Java 库或应用程序的默认设置。但是,如果您有自定义配置或更高级的设置,您还应该将此约束添加到其他配置中。

此外,如果您使用Gradle 模块元数据发布带有此类约束的库,则如果任何使用您的库的构建尝试解析有漏洞的 log4j-core 版本,也会导致它们失败。

4. 防止在组织范围内使用有漏洞的 Log4j 版本 #

您的组织可能会利用应用于所有项目的共享插件。在这种情况下,您还可以将上述约束应用于组织中的所有项目。

如果您使用预编译脚本插件,只需将上面的代码段复制到应用于所有 JVM 项目的脚本中。如果您使用二进制插件,则以下是与 DSL 代码段等效的 Java 代码

project.getDependencies().constraints(constraints -> {
    constraints.add("implementation", "org.apache.logging.log4j:log4j-core", c -> {
        c.version(v -> {
            v.strictly("[2.17, 3[");
            v.prefer("2.17.0");
        });
        c.because("CVE-2021-44228, CVE-2021-45046, CVE-2021-45105: Log4j vulnerable to remote code execution and other critical security vulnerabilities");
    });
});

保护您的构建依赖 #

更新(2021 年 12 月 15 日):您无需将其应用于 Gradle 7.3.2 及更高版本。Gradle 自动要求 Log4J 版本为 2.16.0 或更高版本。

更新(2021 年 12 月 22 日):您无需将其应用于 Gradle 7.3.3 及更高版本。Gradle 自动要求 Log4J 版本为 2.17.0 或更高版本。对于仍在使用 6.x 系列的用户,Gradle 6.9.2 也执行此操作。

除了项目依赖项之外,您的项目可能还使用内部或第三方 Gradle 插件。这些插件也有自己的依赖项,可能会意外地将有漏洞的 Log4j 依赖项引入到构建类路径中。

换句话说,您的构建逻辑可能与您的生产代码以相同的方式容易受到攻击。虽然此类漏洞可能更难利用,但您也可以使用以下代码段保护您的构建依赖项

buildscript {
    dependencies {
        constraints {
            classpath("org.apache.logging.log4j:log4j-core") {
                version {
                    strictly("[2.17, 3[")
                    prefer("2.17.0")
                }
                because("CVE-2021-44228, CVE-2021-45046, CVE-2021-45105: Log4j vulnerable to remote code execution and other critical security vulnerabilities")
            }
        }
    }
}

该代码段应应用于每个构建脚本中的 buildscript 块以及 settings.gradle(.kts) 文件,并确保只有 Log4j 2.17.0 及更高版本可以解析为构建依赖项。该语句必须位于文件的顶部。

保护插件门户用户 #

鉴于最初 Log4j 漏洞的严重性,Gradle 团队希望改善插件门户用户的状况。我们正在采取措施,以确保没有新的插件可以依赖有漏洞的 Log4j 版本。以下更改已可用,将在以后的更新中强制执行。

作为 Gradle 插件作者,您可能直接或间接地依赖于有漏洞的 Log4j 版本。为了保护您的插件用户,Gradle 已在其 plugin-publish 插件中添加了新的验证规则。

我们已发布 Plugin Publish Plugin 的 0.19.0 版本,该版本会自动检测有漏洞的 Log4j 插件依赖项,如果发现任何依赖项,则会通过使构建失败来阻止插件发布。没有自动升级,因为通常 Gradle 插件不需要 Log4j,因为 Gradle 运行时不使用此库进行日志记录。修复问题(删除依赖项或升级它)是插件作者的工作。

在不久的将来,使用此版本的 Plugin Publish Plugin 将成为强制性的,插件门户将拒绝使用旧版本插件完成的任何发布。

Gradle Enterprise 产品 #

一些 Gradle Enterprise 产品受到了 Log4j 漏洞的影响。

Gradle Enterprise、Test Distribution Agent 和 Build Cache Node 的新版本于 2021 年 12 月 13 日发布。

更新(2021 年 12 月 22 日):Gradle Enterprise 2021.4 将 Log4j 升级到 2.17.0

反馈 #

如果您对我们的论坛Gradle 社区 Slack 有任何疑问,请告知我们。

讨论