Introduction
This project intends to debunk two common misbeliefs regarding the impact of the recently discovered Log4j 2.x vulnerabilities on Java applications for two typical scenarios, as reported by the following CVE records:
The first two, famously nicknamed Log4Shell, enable Remote-Code-Execution, while the last one allows a Denial-of-Service.
Misbelief #1: All Log4j modules from 2.0 to 2.16 were impacted by at least one of these vulnerabilities
Unfortunately, only the description of first CVE explicitly says that only the log4j-core
module was affected but the other two are vague on this impact. The official Apache Log4j Security Vulnerabilities page, more accurately states that only the log4j-core
was impacted by the 3 recent vulnerabilities. Therefore, we can safely claim that:
Your application is immune to those three vulnerabilities if it does not include the
log4j-core
module in the runtime classpath.
Misbelief #2: If log4-core older than 2.17 is present in the classpath, then my application is necessarily vulnerable
This one is more subtle. Many applications are based on Spring Boot that by default uses Logback as its logger, but also includes some Log4j modules to bridge the Log4J API to SLF4J/Logback, namely:
log4j-to-slf4j
log4j-api
Not rarely, the log4j-core
is also indirectly included on the runtime classpath by some application dependency. At the end, we have two available implementations (aka "providers") that can be used when the Log4j API is used directly.
As per implemented on Log4j's LogManager initialization code, only one provider is used, the one with higher priority. Luckily, log4j-to-slf4j
has higher priority (15) than log4j-core
(10), ultimately renegating any vulnerable log4j-core
module into an "inert pathogen". Again, we can conclude that:
Your application is also immune if it contains both
log4j-to-slf4j
andlog4j-core
in the runtime classpath.
Branches
Branch | Test |
---|---|
master | Both log4j-to-slf4j and log4j-core are in the RT classpath |
only-log4j | Only log4j-core on the RT classpath |
For all branches, we're using the old, unpatched, Log4j v2.14.1.
How to run
First, build the application binary with:
$ ./gradlew installDist
Then run the application with no arguments to see the instructions:
$ ./build/install/log4j-test/bin/log4j-test