Skip to main content

Log4Shell Update: Second log4j Vulnerability Published (CVE-2021-44228 + CVE-2021-45046)

· 8 min read
Free Wortley
Chris Thompson
Forrest Allison

Log4Shell Logo

Originally Posted @ December 14th & Last Updated @ December 19th, 3:37pm PST

Just trying to fix this? Please read our dedicated Mitigation Guide.

After the log4j maintainers released version 2.15.0 to address the Log4Shell vulnerability, an additional attack vector was identified and reported in CVE-2021-45046.

Our research into this shows that this new CVE invalidates previous mitigations used to protect versions 2.7.0 <= Apache log4j <= 2.14.1 from Log4Shell in some cases.

Conditions for the vulnerability

You may still be vulnerable to Log4Shell (RCE), if you only enabled the formatMsgNoLookups flag or set %m{nolookups} when you also set data in the ThreadContext with attacker controlled data. In this case, you must upgrade to >= 2.15.0, or else you will still be vulnerable to RCE.

For version 2.15.0

Update There has been a limited RCE discovered in 2.15.0, and the severity has been upgraded from 3.7 -> 9.0.

We found that the DOS outlined in the CVE was not actually impactful because it did not consume resources during our testing (see below).

Our reproduction could be incomplete however, so we continue to recommend that you upgrade to 2.17.0 in the event that a better exploit is found to abuse this attack vector.

The new CVE is difficult to understand

The mention of possible RCE is unfortunately missing from the published CVE. In the CVE it only mentions a possible "Denial-of-Service" attack for versions prior to 2.15.0 and 2.16.0.

Because of these findings, we recommend that everybody using log4j immediately upgrades to 2.17.0 or later, or manually patches their log4j classes (for details, see our Mitigation Guide). Please read the rest of this post for context about our research.

Context on CVE-2021-45046

The new CVE states:

It was found that the fix to address CVE-2021-44228 in Apache Log4j 2.15.0 was incomplete in certain non-default configurations.

We found this report concerning as it states that one of the recommended temporary mitigations for versions 2.7.0 <= Apache log4j <= 2.14.1 might not protect against this CVE. Further:

Note that previous mitigations involving configuration such as to set the system property log4j2.formatMsgNoLookups to true do NOT mitigate this specific vulnerability.

It was not readily apparently from reading this CVE what specifically was affected, or how this vulnerability is actually triggered. That's why we actually tested this ourselves to figure out what the impact was.

Testing previous mitigations

Fortunately the community has been hard at work reacting to these updates. A fork of christophetd/log4shell-vulnerable-app has added some changes to demonstrate the specific scenario in which this newly found CVE could affect an application.

In these changes, the previously discovered mitigation was included:

# Add environment variable as the currently official workaround for vulnerable versions of log4j2 (e.g. 2.14.1)
ENV LOG4J_FORMAT_MSG_NO_LOOKUPS true

And the Log4j2 properties config includes a custom layout pattern:

# ...
# vulnerable in 2.14.1 even with ENV LOG4J_FORMAT_MSG_NO_LOOKUPS true
appender.console.layout.pattern = ${ctx:apiversion} - %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# ...

Now, instead of directly logging the attacker controlled input as with the previous vulnerability like this:

@GetMapping("/")
public String index(@RequestHeader("X-Api-Version") String apiVersion) {
logger.info("Received a request for API version " + apiVersion);
return "Hello, world!";
}

In the layout pattern above, the ${ctx:apiversion} format string refers to a ThreadContext value named apiversion. In order to trigger the vulnerability, there needs to be code which lets the attacker influence the apiversion value. The below handler demonstrates what this might look like in code:

@GetMapping("/")
public String index(@RequestHeader("X-Api-Version") String apiVersion) {

// Add user controlled input to threadcontext;
// Used in log via ${ctx:apiversion}
ThreadContext.put("apiversion", apiVersion);

// Notice how these changes remove apiVersion from directly being logged
logger.info("Received a request for API version");
return "Hello, world!";
}
Vulnerable App Log4j version

This vulnerable application was running with Log4j version 2.14.1, which is still vulnerable to the RCE even before the LOG4J_FORMAT_MSG_NO_LOOKUPS mitigation.

Our Findings

Issues when using log4j2.formatMsgNoLookups (>=2.10.0)

Running this vulnerable server and exploiting the vulnerability with our log4shell CLI tool, we observed that RCE was still possible in versions 2.10.0 <= Apache log4j < 2.14.1:

Log4j RCE on log4j 2.14.1 with mitigation

The server is still vulnerable even with log4j2.formatMsgNoLookups enabled because the Pattern Layout has been modified to include a reference to a Thread Context value. It appears that referencing Thread Context values in this way bypasses the logic for disabling JNDI lookups when formatting a message. The CVE report outlines this as well as the other types of affected format strings:

This could allow attackers with control over Thread Context Map (MDC) input data when the logging configuration uses a non-default Pattern Layout with either a Context Lookup (for example, $${ctx:loginId}) or a Thread Context Map pattern (%X, %mdc, or %MDC) to craft malicious input data using a JNDI Lookup pattern.

We were not able to achieve RCE when using %X, %mdc, or %MDC, however we still do not consider these as safe to include when running a Log4j version < 2.16.0. To understand more about the Log4j Thread Context map, please refer to the docs.

If you have previously used LOG4J_FORMAT_MSG_NO_LOOKUPS to mitigate the log4shell vulnerability, in certain conditions this will not be sufficient to protect your code from RCE. Refer to our mitigation guide for additional steps you can take to remediate the impact of Log4Shell.

Setting %m{nolookups} is still vulnerable (>=2.7.0)

We continue to recommend not using %m{nolookups}, as explained in our mitigation guide, since we have proven the vulnerability is still exploitable with a Pattern Layout such as:

appender.console.layout.pattern = ${ctx:apiversion} - %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m{nolookups}%n

%m{nolookups} will only apply to the content being logged in the call to logger.info(), and will not apply to the resolving of ${ctx:apiversion} which will contain our payload.

Notes on the Denial-of-Service in 2.15.0

Update There has been a limited RCE discovered in 2.15.0, and the severity has been upgraded from 3.7 -> 9.0.

The less impactful part of this CVE, if you have updated your Log4j version to 2.15.0, is that there is a limited denial of service (DOS), possible under certain circumstances. See the below screenshot:

Log4j DOS on log4j 2.15.0 with mitigation

However, in our testing we did not find this DOS to be resource consuming, as it seemed that the infinite loop created by recursively resolving ${ctx:apiversion} was identified by the program and errored out.

Log4j 2.16.0 completely mitigates this issue by removing support for message lookup patterns and disabling JNDI functionality by default. 2.16.0 has its own issues, however, so please upgrade to 2.17.0 or newer.

Stay Updated

Please follow us on Twitter or add yourself to our mailing list below, and we'll update you when we publish new findings.

If this post helped you, please share it with others.

Additional Information

We have published a series of posts about Log4Shell on our blog that you might be interested in:

Limited Offer: Free Security Assistance

We're also currently offering a free 30-minute consultation with one of our Security Engineers. If you're interested, please book some time with us here.

Updates

info

We're continuously keeping this post up-to-date as new information comes out. If you have any questions, or you're confused about our advice, please file an Issue on GitHub.

If you would like to contribute, or notice any errors, this post is an Open Source Markdown file on GitHub.

  1. Updated 12/15/21: Updated "Conditions for the Vulnerability" section from "upgrade to 2.16.0" to "upgrade to >= 2.15.0", see this GitHub issue.
  2. Updated 12/15/21: Updated all instances of noFormatMsgLookup to be the correct formatMsgNoLookups, see this GitHub issue.
  3. Updated 12/16/21: Added links to other blog posts.
  4. Updated 12/18/21: Updated note about 2.15.0 that RCE has been found.
  5. Updated 12/19/21: Updated advice about 2.16.0 to recommend 2.17.0 now.