Preparing for Java and Spring Boot Interview?

Join my Newsletter, its FREE

Monday, December 13, 2021

What is Log4j 2 RCE issue CVE-2021-44228? How to solve Log injection? [Tactical and Permanent Fix]

Hello guys, since the last couple of days, there is a lot of chaos going into the Java world due to the Log4j2 issue which allows Remote code execution (RCE), the CVE-2021-44228, which is designated a zero-day vulnerability. Everyone is busy whether their Java application is impacted and given the popularity of Log4j it's a good chance that your application will be impacted.  Even if you are not using Log4j2 directly, they might be used by the framework or library you use like Spring Boot, Hadoop, Elastic Serach, or Struts. This is kind of a serious issue becuase RCE Vulnarabilyt means it allows hackers to execute code in your servers, and this has been used in past on many breaches like the 2017 Equifax data breach but its not time to lose calm and understand the impact and whether your app is affected or not and what you can do in short term to prevent it. 

But first, let's see what is the issue itself

Log4j2 is a logging library that is used to log messages. Since Java is the most popular server-side programming language and logging is a must in server-side apps, Log4j has been used widely and holds the title of the most popular logging library for Java developers. I myself have used log4j in many projects. 

The problem is that it also supports formatted string and there is one format that instructs Log4j to download a class from a remote server using LDAP protocol which can be used to execute remote code and cause this zero-day vulnerability. 

I know, you might be thinking what? Why does Log4j need to download a class and yes, that puzzled me and many others but that's the reality and we will earn more about the issue and its tactical and strategic solution in this article. 

What exactly is the Log4j2 issue and RCE Vulnerability?

The Job of a logging library is to write messages to the destination, it could be a file or a database. Over the year, logging evolved and most of the time your logging message is not a simple message but a message with variables something like Logger.log("This message is from {username}"); Yes, I am talking about placeholders that are resolved at runtime. 

Log4j has a magical feature that allows it to look up into a remote server to resolve such variables (well, I didn't know about that feature before, just got to know about it due to the issue). 

Now, this feature not only looks to resolve content from a remote server, which could be a bad or evil server but also it doesn't sanitize the value it receives.

For example, you would expect that Logger.log("This message is from {username}") the username variable will be sanitized to remove any special character and treat it as text rather than code but Log4j2 doesn't do that. 

What is Log4j 2 issue? Should you be worried about Log injection?

It's very similar to SQL injection which is told to us but in this case, even the solution of SQL injection is causing Log injection. I mean, when I learned SQL injection I understand that string concatenation is bad and you should use PreparedStatement and Placeholders to sanitize user input before sending it to the database. 

I mean 

Logger.log("This message is from" + username) ;  // This was bad
Logger.log("This message is from {username}")   // This was good 
// but it's not good in the case of Log4j2.

Due to this, we are not facing the vulnerability which will impact many Java applications but only if they are externally exposed.

Who is impacted by the Log4j2 issue?

As per my research, anyone using the Log4j version greater than 2.0 and less than or equal to Log4j 2.14.1 are impacted. This is triggered if you are using formatted string for logging becuase in this version the remote lookup feature is by default enabled. 

But, in order to take advantage of this feature hackers need to have control of your app which they can gain if you have any TCP, HTTP, or REST endpoints and also if you are logging user input into a log using Log4j versions which have this vulnerability. 

This means:
1. If your app doesn't have any endpoints then it's not impacted
2. If it's running on Log4j1.x then it's not impacted
3. If your app is running on JDK versions greater than 6u211, 7u201, 8u191, and 11.0.1 then they are not affected because in these versions com.sun.jndi.ldap.object.trustURLCodebase is set to false meaning JNDI cannot load remote code using LDAP.

However, there could be more ways to target this vulnerability that can result in RCE.  For example, an attacker could still leverage existing code on the server to execute a payload. An attack targeting the class org.apache.naming.factory.BeanFactory, present on Apache Tomcat servers can be possible, as discussed here

How to solve this Lo4j2 RCE issue?

The permanent but non-trivial solution is to upgrade to a Log4j2 version that doesn't have this vulnerability. For example  Version 2.15.0 of log4j has been released without the vulnerability. log4j-core.jar is available on Maven Central which you can download and upgrade. 

But if you are running anywhere close to the real-world system then you know that it's a non-trivial exercise and you may be required to update a couple of other libraries. 

The other solution suggested by CVE website is to disable this feature by settin gup system property "log4j2.formatMsgNoLookups" to true; or by removing the JndiLookup class from the classpath (example: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class)

You can also upgradde Java version to higher version where this lookup is not allowed. For example, Java versionn 8u121 protects against remote code execution by defaulting "com.sun.jndi.rmi.object.trustURLCodebase" and "com.sun.jndi.cosnaming.object.trustURLCodebase" to "false". 

2. Alternative solution using SLF4j and Logbak

There is another way to solve the problem by replacing Log4j2 with SLF4J and then using LogBak. If you remember SLF4j is just an API that provides an abstraction over logging API and the main advantage of using SLF4j is that you can replace the underlying logging library without changing the code. I mean you can replace the underlying library Log4j2 with Logbak which doesn't have this vulnerability. 

If you remember, I advised long back that why Java developers should use SLF4j over log4j  but at that time I didn't think that this step can be so useful. 

In case, if you are not using SLF4j then you may or may not require some code changes. At first, you should just try to replace the log4j JAR with an SLF4j jar and replace the config with a Logbak config (XML) and see if it works. 

And, here is a nice diagram that explains how Log4j can run the remote code:

What is Log4j 2 RCE issue CVE-2021-44228? How to solve Log injection? [Tactical and Permanent Fix]

That's all about this Log4j2 RCE vulnerability issue and how to deal with it, The situation is still evolving as it's gaining more and attention. I will update this article with more info as and when I get but there is a lot of content already available on the web if you are want to learn more. 

Further Learning
Here are the links for some of the useful posts I found on this Log4j2 issue:

1. THis HackerNews thread -

2. Lunasec' Log4Shell: RCE 0-day exploit found in log4j 2,

3. CVE page where this issue is tracked -

4. Blog post on Sonatype blog - Critical New 0-day Vulnerability in Popular Log4j Library Discovered  with Evidence of Mass Scanning for Affected Applications

5. CVE-2021-44228 - Log4j RCE 0-day mitigation on CloudFlare blog -

If you find more information about the impact and any other quick way to solve this problem, feel free to share in the comments. This is the most widely impacted vulnerability issue I have seen in my career as a Java developer and I am sure I am not alone.

No comments :

Post a Comment