Log4Shell (CVE-2021-44228) is more than four years old, and it is still the reference point for every "how did this get in?" conversation. If you are building a detection playbook today, Log4j is the right template — not because it is current, but because it shows exactly how a logging library becomes a remote code execution vector.
The mechanism in one paragraph
Log4j's message substitution feature let a logged string trigger a JNDI lookup. An attacker who could get an application to log a crafted string — a username, a user-agent, a header — could make the JVM connect to an attacker-controlled LDAP or RMI server and load a payload. No authentication, no user interaction beyond the request.
The lesson generalises: any component that parses structured input and then acts on it is a potential execution surface. Logging frameworks are just the most common example.
Detection: find it before you patch it
Manual auditing does not scale. You need automated Software Composition Analysis (SCA) that reads your build files and produces a Software Bill of Materials (SBOM).
- Scan
pom.xml,build.gradle, and runtime libraries forlog4j-coreversions between 2.0-beta9 and 2.14.1. - Treat transitive dependencies as first-class findings — Log4j is rarely a direct dependency in modern frameworks.
- Complement SCA with network monitoring: outbound LDAP/RMI connections from application servers that do not normally make them are a strong signal.
Short-term mitigation
When you cannot upgrade immediately:
- Set
log4j2.formatMsgNoLookups=trueon affected JVMs. Be aware that bypasses were documented for some versions, so this is a speed bump, not a fix. - Add WAF rules that inspect headers and request bodies for
${jndi:ldap://...}patterns. Attackers can obfuscate these, so treat the rule as a deterrent, not a guarantee. - Block outbound connections from application hosts to the internet at the firewall where possible.
Patching
For Maven:
<!-- Before -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.10.0</version>
</dependency>
<!-- After -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>
If Log4j is bundled inside a larger framework, prefer upgrading the framework to a version that ships the patched library. If that is not possible, use dependency exclusions to force the safe version across all modules.
After the patch
- Regression-test logging specifically. A major version jump can change log output or break custom appenders.
- Never pass raw user input directly into a logger call. Sanitise or encode before the value reaches the logging statement.
- Run the logging service account with minimal permissions, and segment your log aggregation platform from production assets.
- Integrate SCA into CI so a future CVE fails the build instead of reaching production.
The pattern to remember
The Log4j story is not really about Log4j. It is about a trusted, ubiquitous component that interpreted input it should have treated as data. The controls that matter — dependency inventory, least privilege, network egress filtering, and CI gates — are the same ones that protect you against the next one.
This is an expanded technical note based on our Log4j detection and patching guide. The original is here: https://hsecurities.in/blog/detect-patch-log4j-vulnerability
Top comments (0)