This is an automated email from the ASF dual-hosted git repository.
ppkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-site.git
The following commit(s) were added to refs/heads/main by this push:
new f4b1a4ff Add threat model and FAQ entry about deserialization (#29)
f4b1a4ff is described below
commit f4b1a4ff98374e75b1356882e85adf4111b6454c
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Mon May 4 22:52:35 2026 +0200
Add threat model and FAQ entry about deserialization (#29)
This change adds a section about deserialization of untrusted data to both
the threat model and security FAQ.
---
.../modules/ROOT/pages/_threat-model-common.adoc | 16 ++++++
.../antora/modules/ROOT/pages/security/faq.adoc | 61 +++++++++++++++++++++-
2 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/src/site/antora/modules/ROOT/pages/_threat-model-common.adoc
b/src/site/antora/modules/ROOT/pages/_threat-model-common.adoc
index 64baf472..2ebd7b7d 100644
--- a/src/site/antora/modules/ROOT/pages/_threat-model-common.adoc
+++ b/src/site/antora/modules/ROOT/pages/_threat-model-common.adoc
@@ -141,3 +141,19 @@
https://logging.apache.org/log4j/2.x/manual/api.html#best-practice-concat[Log4j
Improper neutralization of Special Elements
(https://cwe.mitre.org/data/definitions/138.html[CWE-138])::
+
* Log4cxx, Log4j, and Log4net **do** allow users to pass untrusted strings to
log statements and thread context, except in the format string of parameterized
logging, as mentioned above.
+
+Deserialization of untrusted data
(https://cwe.mitre.org/data/definitions/502.html[CWE-502])::
++
+Log4cxx, Log4j, and Log4net **do not** deserialize data from any source as
part of their normal operation.
+For backward compatibility, several classes in Log4j 2 and Log4net 2 still
implement `Serializable` (in Java) or carry the `[Serializable]` attribute (in
.NET); Log4j's `log4j-api` also ships an allowlist-based
`FilteredObjectInputStream` utility to assist applications that nonetheless
deserialize log event streams.
++
+--
+Regarding this threat:
+
+* We provide **no guarantee** that deserializing a stream containing classes
from these projects is safe, regardless of the source of the stream.
+* Filtering such a stream by the `org.apache.logging` Java package, the
`log4net` .NET namespace, or any allowlist derived from project-owned types is
**not** sufficient to make deserialization safe.
+* The hardening utilities we ship are **partial** and **not exhaustive**;
bypasses are treated as opportunities for further hardening, not as
vulnerabilities in the project.
+* The application performing the deserialization is responsible for ensuring
that the byte stream originates from a **trusted source**.
+--
++
+See xref:security/faq.adoc#deserialization[the FAQ entry on CWE-502] for the
recommended alternatives.
diff --git a/src/site/antora/modules/ROOT/pages/security/faq.adoc
b/src/site/antora/modules/ROOT/pages/security/faq.adoc
index 05f5e5a5..e834f80a 100644
--- a/src/site/antora/modules/ROOT/pages/security/faq.adoc
+++ b/src/site/antora/modules/ROOT/pages/security/faq.adoc
@@ -163,4 +163,63 @@ The trustworthiness of an interpolation source cannot be
determined a priori by
Consider `${ctx:...}` lookups as an example: some applications populate the
thread context map exclusively with internally generated values (such as
request IDs), while others may include user-provided data (such as HTTP
headers).
In practice, trustworthiness often varies even at the per-key level: some
context map keys may be safe to use in file paths, while others may not.
-====
\ No newline at end of file
+====
+
+[#deserialization]
+== https://cwe.mitre.org/data/definitions/502.html[CWE-502: Deserialization of
Untrusted Data] in Log4j
+
+A frequently reported issue concerns Log4j's `Serializable` classes and the
allowlist-based `FilteredObjectInputStream` utility shipped in `log4j-api`.
+Reports typically claim that, taken together, these expose Log4j to
deserialization-based remote code execution when an attacker reaches a
deserialization sink.
+
+**Claim**: Log4j is vulnerable to deserialization of untrusted data because
some of its classes are `Serializable` without hardening logic that guarantees
secure deserialization, allowing an attacker who reaches a deserialization sink
to construct a gadget chain through them.
+
+[#deserialization-why-not]
+=== Why this is not a vulnerability
+
+Log4j Core **does not** deserialize data from any source as part of its normal
operation.
+There is no code path in current Log4j Core production code that reads bytes
from a network socket, a message queue, or any other input and passes them to
`ObjectInputStream.readObject()`.
+
+For a deserialization vulnerability to exist, an application must:
+
+* Obtain a stream of bytes from an untrusted source, _and_
+* Pass those bytes to `ObjectInputStream.readObject()` (or an equivalent API).
+
+Both of these steps occur **outside** Log4j.
+The fact that Log4j classes happen to appear in such a stream does not make
Log4j the source of the vulnerability, any more than the presence of
`java.util.HashMap` in a gadget chain makes the JDK responsible for it.
+
+Log4j provides **no guarantee** that deserializing a stream containing its
classes from an untrusted source is safe, and reports premised on the
assumption that such a guarantee exists fall outside our
xref:security.adoc#threat-model[threat model].
+
+[#deserialization-historical-context]
+=== Historical context
+
+Log4j 1 shipped a `SocketServer` and a `SocketAppender` that exchanged log
events over the network using Java serialization.
+
+In Log4j 2:
+
+* The `SocketServer` receiver was never reintroduced into the production
codebase.
+* `SerializedLayout`, originally provided for Log4j 1 compatibility, has been
**deprecated since version 2.9** and should not be used.
+See the
{site-url}/log4j/2.x/manual/layouts.html#SerializedLayout[SerializedLayout
documentation] for details.
+* Several Log4j 2 classes, most notably `Logger`, `Message` and `LogEvent`,
remain `Serializable` for backward compatibility.
+The `Serializable` interface cannot be removed in a minor release without
breaking applications that rely on it.
+
+In Log4j Core 3, the `Serializable` interface has been removed from these
classes.
+
+[#deserialization-filtered-object-input-stream]
+=== About `FilteredObjectInputStream`
+
+The Log4j API provides a `FilteredObjectInputStream` utility that enforces a
class allowlist when deserializing log event streams.
+This class exists as a **defense-in-depth helper** for applications that,
despite the guidance above, still consume serialized log events.
+
+`FilteredObjectInputStream` is **not** a security boundary, and the project
makes no guarantee that its allowlist is exhaustive or bypass-proof:
+
+* Reports of allowlist bypasses are evaluated as **hardening opportunities**,
not as vulnerabilities in Log4j.
+* The underlying unsafe operation, deserializing untrusted bytes against a
classpath that exposes arbitrary `Serializable` classes, is performed by the
consuming application, not by Log4j.
+
+[IMPORTANT]
+====
+If your application deserializes log event streams from any source you do not
fully control, you are performing an operation that the Logging Services PMC
does not endorse and cannot make safe.
+Recommended alternatives include:
+
+* Migrating to a structured layout such as JSON or RFC 5424, transported over
TLS.
+* If serialized transport must be retained for legacy reasons, configuring a
JVM-wide serialization filter via `jdk.serialFilter` and ensuring the producer
and consumer endpoints are mutually authenticated and not exposed to untrusted
networks.
+====