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.
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
totrue
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!";
}
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
:

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:

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:
- Mitigation Guide
- Original Log4Shell Announcement
- Part 1: Log4Shell Live Patch (Background Context)
- Part 2: Log4Shell Live Patch (Technical Deep-Dive)
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
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.
- 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. - Updated 12/15/21: Updated all instances of
noFormatMsgLookup
to be the correctformatMsgNoLookups
, see this GitHub issue. - Updated 12/16/21: Added links to other blog posts.
- Updated 12/18/21: Updated note about 2.15.0 that RCE has been found.
- Updated 12/19/21: Updated advice about 2.16.0 to recommend 2.17.0 now.