Follow Cyber Kendra on Google News! | WhatsApp | Telegram

Add as a preferred source on Google

Log4j Deserialization Bypass Is Real but Not Log4Shell

Log4j deserialization bypass

A security researcher using the handle U-Sec (Wujie Security) published details of a deserialization filter bypass in Apache Log4j 2, reporting that the framework's FilteredObjectInputStream allowlist can be sidestepped with java.rmi.MarshalledObject to smuggle arbitrary objects past its class checks.

Two days later, the report was stripped of its contents, renamed, and closed, and the researcher's GitHub account was deleted — but by then a Log4j maintainer had already documented the same behaviour publicly as a hardening item rather than a vulnerability.

No CVE has been assigned, and the report listed no CVSS score. The flaw is a deserialization allowlist bypass (a safety filter meant to block dangerous classes is tricked into permitting them), said to affect log4j-api 2.11.0 through the current 2.26.1. 

Cyber Kendra archived the original report before it was removed, independently verified its technical claims against Apache's published source, and found that the Log4j project itself had catalogued the exact same code path seven weeks earlier. The mechanism is real. The "critical RCE" framing is not the one Apache uses.

The Short Version

  • Is it real? Yes — the FilteredObjectInputStream allowlist bypass via java.rmi.MarshalledObject is confirmed in Log4j 2.26.1 source.
  • Is it another Log4Shell? No. Log4Shell fired on any logged string; this needs an application that deliberately deserializes untrusted LogEvent objects — not a default configuration.
  • Is there a CVE? No CVE and no patch. A Log4j maintainer had already logged the same behaviour on 1 July as a hardening item, "not a security issue".
  • What should I do? Don't deserialize untrusted data; if you run a serialized-log receiver, apply a JVM-wide serialization filter (JEP 290).

How the Log4j Filter Bypass Works

Log4j added FilteredObjectInputStream in 2017, after CVE-2017-5645, a socket server flaw that allowed a crafted binary payload to run code when deserialized. The fix, shipped in 2.8.2, introduced an allowlist of classes permitted during the rebuilding of a serialized log event — everything else is rejected.

The reported weakness lies in what the allowlist lets through. It permits java.rmi.MarshalledObject, a standard Java class that stores its wrapped object as an opaque byte array. The filter inspects only the top-level class of each object it resolves; it never looks inside that byte array. 

When Log4j reconstructs the event, Log4jLogEvent.LogEventProxy calls .get() on a marshalled-message field, and .get() spins up a fresh ObjectInputStream with no filter attached. Whatever classes sit inside those bytes are then deserialized unchecked, so any usable gadget class on the application's classpath becomes reachable. Cyber Kendra is withholding payload specifics.

What Cyber Kendra Confirmed in the Source

We checked each link in the chain against the shipping Log4j 2.26.1 source rather than relying on either the researcher's or the maintainer's description. All four are present in the current release:

Claimed causeLocationStatus
Allowlist permits java.rmi.MarshalledObjectSerializationUtil (log4j-api)Confirmed — listed with the comment "for Message delegate"
Filter sees only the outer class, never the wrapped bytesFilteredObjectInputStream.resolveClass()Confirmed — checks one class name; no stream filter set
Event proxy carries a non-transient MarshalledObject fieldLog4jLogEvent.LogEventProxy (log4j-core)Confirmed
.get() called during rebuild, exceptions swallowedLogEventProxy message helperConfirmed — unfiltered, wrapped in try/catch

On the technical merits, this is not a fabrication. The bypass mechanism exists in code, and the allowlist entry is deliberate.

Apache Already Documented This — as Hardening, Not a Bug

On 1 July 2026, Log4j maintainer Piotr P. Karwasz opened a public GitHub discussion listing five deserialization findings surfaced during a review. The first, marked "High" priority, describes the marshalledMessage field, the readResolve()message()marshalledMessage.get() call chain, and the fact that MarshalledObject's private stream "does not inherit Log4j's per-stream filter" — the same finding U-Sec would post as a critical vulnerability on 24 August.

The framing is the whole story. Karwasz's post opens by stating plainly, "These are not security issues." It reiterates the project's threat model: "Log4j does not deserialize data as part of normal operation," and filtering the stream by Java package is "not sufficient to make deserialization safe." The list is explicitly labelled "hardening" — the defensive tightening of a layer that was never a security boundary, not the patching of an exposed hole.

The Maintainer's Verdict: "A Known Security Non-Finding"

When Karwasz responded directly to the withdrawn report, he was blunt about what it was: "an independent discovery of a known security non-finding," citing Apache's standing FAQ on deserialization of untrusted data. FilteredObjectInputStream, he wrote, "is a hardening measure and never was a trust boundary."

He confirmed the research was technically correct, then explained why that does not make it a vulnerability:

The report itself is accurate on the details: java.rmi.MarshalledObject is on the allowlist, MarshalledObject.get() opens a fresh unfiltered stream. None of that changes the precondition. You still need an application feeding untrusted bytes to a Java deserialization endpoint, and once you have that, you have remote code execution with or without this allowlist entry.

That is the line for defenders to internalise. If an application deserializes untrusted data through Java ObjectInputStream at all, it is already exposed to remote code execution — a hazard OpenJDK documents itself. The MarshalledObject allowlist entry is a missing hardening bolt on a door that was never built to face untrusted input, not a breach in a wall.

On a fix, Karwasz pointed back to discussion #4168, open since July precisely to see whether any user wants to implement the extra hardening. None has volunteered, so — in his words — the project's "limited volunteer time can be spent on more useful tasks. Patches are welcome." He was categorical on the rest: "No CVE, no embargo, nothing here that needs to be kept confidential." What actually made the issue notable, he added, was that it "was nearly deleted before anyone had triaged it."

Which Log4j Versions Are Affected

The report listed log4j-api 2.11.0–2.26.1 and log4j-core 2.8.0–2.26.1. Version 2.26.1 is the current release, published on 2 July 2026, so the code is present in the newest build.

One detail bounds the risk. The socket-server classes that once received serialized log events over the network — TcpSocketServer and UdpSocketServer in the net.server package — were removed from log4j-core in version 2.9.0 and moved to a separate, unreleased tools module. Every version of the report flags already shipped without that listener.

Why This Is Not a Second Log4Shell

Log4Shell (CVE-2021-44228, CVSS 10.0) was catastrophic because it needed nothing from the victim beyond logging a string. Any attacker-controlled value that reached a log call triggered a JNDI lookup, fetching remote code. The attack surface was on by default in effectively every application using Log4j, and it was wormable at internet scale.

This is a different shape. To reach the deserialization sink, an application must deliberately stand up a service that reads serialized LogEvent objects through FilteredObjectInputStream, expose it to untrusted input, and carry exploitable gadget classes on its classpath. 

A containerised proof-of-concept published after the report does achieve code execution — but its own documentation states it requires "an unauthenticated FOIS-based serialized-LogEvent receiver," a component the lab has to build for itself because stock Log4j no longer ships one. That is the precise condition Apache warns against: its security policy says there is "no guarantee that deserializing a stream ... is safe, regardless of the source." The bypass is genuine; the exposure is opt-in and rare.

What Happened to the Report

Cyber Kendra verified the following directly against the live issue page:

DateEvent
1 Jul 2026Log4j maintainer opens discussion #4168, documenting the MarshalledObject path (and four other findings) as "High"-priority hardening, explicitly "not security issues".
24 Aug 2026Issue #4255 opened by U-Sec, presenting the same path as a critical, unpatched RCE with root-cause analysis, logs and a reproduction sketch. Labelled waiting-for-maintainer.
By 26 Aug 2026Title changed to "Something wrong Happen". Body deleted — the page now reads "No description provided." Issue closed.
By 26 Aug 2026Author attribution shows ghost, GitHub's placeholder for a deleted account. The researcher's profile returns a 404.

The withdrawal came from the reporting side, not the project: the report was emptied and closed, and the account deleted, before Apache formally triaged it. When a maintainer did weigh in (see above), it was to reaffirm that this is a known non-finding, not to confirm a critical RCE — Karwasz noted the issue "was nearly deleted before anyone had triaged it." 

The plain reading of the episode is that a genuine but already-documented hardening gap was re-raised as a zero-day, and could not survive contact with the project's existing position. Why the reporter deleted the issue and the account rather than simply correcting course, we cannot say, and we are not going to guess. 

There is history around Log4j disclosure — in December 2021, China's industry ministry suspended a partnership with Alibaba Cloud for reporting Log4Shell to Apache before notifying the government — but that concerned a different flaw, and nothing links it to this withdrawal. Either way, the verification above stands on Apache's own source and does not depend on the report or the account continuing to exist.

Has Apache Patched It?

There is nothing to patch in the vulnerability sense, and no CVE or advisory has been issued — the maintainer was explicit: "no CVE, no embargo." 

The obvious hardening candidate, removing MarshalledObject from the allowlist, remains an open invitation in discussion #4168 rather than committed work; no contributor has volunteered to implement it, and Apache spends its volunteer time elsewhere. 

Independent write-ups back up the assessment: Sonatype notes, "Apache does not treat the filter as a complete security boundary," and the reproduction firm Pruva, which built a working lab, still classifies the result as "conditional" and "not typical Log4j usage." The three Log4j CVEs published earlier in 2026 (CVE-2026-34477 TLS hostname bypass, CVE-2026-34478 log injection, CVE-2026-34480 XML log loss) are unrelated.

How to Reduce Your Exposure

  • Do not deserialize untrusted data, and do not expose services that accept serialized LogEvent objects to networks you do not control.
  • If a serialized-log receiver is unavoidable, apply a JVM-wide serialization filter (jdk.serialFilter, JEP 290). The Log4j allowlist does not propagate into MarshalledObject.get(), so a process-wide filter is the layer that actually covers the nested bytes.
  • Trim unused libraries that provide deserialization gadgets from the classpath.
  • Keep Log4j current and watch logging.apache.org for any allowlist change.

Frequently Asked Questions

What is Apache's official position on the Log4j #4255 flaw?
Apache treats it as a hardening item, not a vulnerability. Maintainer Piotr Karwasz called the report "an independent discovery of a known security non-finding," reaffirming that FilteredObjectInputStream "is a hardening measure and never was a trust boundary" and that Log4j does not deserialize untrusted data in normal operation. No CVE has been assigned. Independent analyses by Sonatype and the reproduction firm Pruva reached the same conclusion: the mechanism is real, but exposure is narrow and conditional.

Is the new Log4j2 RCE flaw another Log4Shell?
No. Log4Shell (CVE-2021-44228) triggered when any attacker-controlled string reached a log call and was exploitable by default in almost every Log4j application. This deserialization bypass only reaches code execution if an application deliberately runs a service that reads serialized LogEvent objects through FilteredObjectInputStream and exposes it to untrusted input — a rare, opt-in configuration.

Is the Log4j2 FilteredObjectInputStream deserialization flaw real?
Yes. Cyber Kendra confirmed in the shipping Log4j 2.26.1 source that the allowlist permits java.rmi.MarshalledObject, that the filter never inspects the object's nested bytes, and that Log4jLogEvent.LogEventProxy it deserializes those bytes without a filter. The mechanism works; its real-world reachability is narrow.

Which Log4j versions are affected?
The report lists log4j-api 2.11.0 through the current 2.26.1. However, the socket-server component that would receive serialized log events was removed from log4j-core in version 2.9.0, so no shipped version exposes this path by default.

Is there a CVE or patch for the Log4j MarshalledObject flaw?
No CVE has been assigned, and no patch has been released. A Log4j maintainer publicly documented the same behaviour on 1 July 2026 (discussion #4168) as a "High"-priority hardening item, stating explicitly that these are "not security issues".

How do I protect against the Log4j deserialization bypass?
Do not deserialize untrusted data, and do not expose serialized-LogEvent receivers to untrusted networks. Where a receiver is unavoidable, apply a JVM-wide serialization filter (jdk.serialFilter, JEP 290), since the Log4j allowlist does not cover the nested MarshalledObject bytes.

Updates

2026-08-26: Issue #4255 has been renamed to "Something wrong Happen", its body deleted, and the issue closed; the reporting account now shows as ghost. Cyber Kendra has confirmed the underlying code paths in Log4j 2.26.1 and located the maintainer discussion #4168 (1 July), which documents the same behaviour as a hardening measure, not a vulnerability. No CVE or patch has been issued.

2026-08-27: Public exploit tooling appeared — a standalone exploit and a Nuclei detection template from researcher Joan Bono, alongside an earlier containerised lab. Both still require the same non-default precondition: an exposed serialized-LogEvent receiver on FilteredObjectInputStream, plus a deserialization gadget on the classpath. Defenders should treat the issue as trivially scannable and check for legacy log-socket receivers (commonly port 4560).

2026-08-27 (later): Maintainer Piotr Karwasz responded to issue #4255, calling it "an independent discovery of a known security non-finding" — the report is technically accurate, but the precondition (an application deserializing untrusted data) is what yields RCE, "with or without this allowlist entry." He confirmed "no CVE, no embargo." 

Reproduction firm Pruva separately published a controlled lab confirming conditional RCE while validating that removing java.rmi.MarshalledObject from the allowlist and a JEP 290 filter each block it. Still no CVE, and Apache maintains that this is not a vulnerability in stock Log4j.

Post a Comment