Skip to content

Apply the deserialization filter in test helpers on Java 9+ - #4270

Open
ppkarwasz wants to merge 1 commit into
feat/2.x/filtered-stream-reject-proxiesfrom
feat/2.x/serial-util-java9-filter
Open

Apply the deserialization filter in test helpers on Java 9+#4270
ppkarwasz wants to merge 1 commit into
feat/2.x/filtered-stream-reject-proxiesfrom
feat/2.x/serial-util-java9-filter

Conversation

@ppkarwasz

Copy link
Copy Markdown
Member

Important

This PR is part of the deserialization hardening work tracked in #4168. The Logging Services PMC does not use nor recommend Java serialization/deserialization, and our security FAQ has long documented this position. This work is submitted solely to reduce the false-positive "vulnerability" reports that keep being filed regardless of that FAQ. Its utility for end users is close to zero.

The SerialUtil test helper returned a plain, unfiltered ObjectInputStream on Java 9 and later, so our test suite only exercised the deserialization allowlist when running on a Java 8 toolchain. This made it possible for a change to the serialized forms to pass CI while being rejected by the filter at runtime.

SerialUtil now installs DefaultObjectInputFilter on Java 9+ (reflectively, since the helper must still compile and run on Java 8), combined with an ObjectInputFilter.Config.createFilter delegate built from the caller-supplied extra allowed classes — reproducing FilteredObjectInputStream's semantics on modern JDKs. When DefaultObjectInputFilter is unavailable — it only exists in the packaged multi-release log4j-api jar, not in classes-dir reactor builds — the helper falls back to FilteredObjectInputStream, which enforces the same allowlist on any Java version.

SerializationTestHelper in log4j-1.2-api now delegates to SerialUtil, so its org.apache.log4j.* extras are honored on all Java versions as well.

Test-only change; no user-visible behavior is affected.

The `SerialUtil` test helper returned a plain, unfiltered
`ObjectInputStream` on Java 9 and later, so the deserialization
allowlist was only ever exercised by tests running on a Java 8
toolchain. It now installs `DefaultObjectInputFilter` (reflectively,
since the class must still compile and run on Java 8), combined with an
`ObjectInputFilter.Config.createFilter` delegate built from the
caller-supplied extra allowed classes, reproducing the
`FilteredObjectInputStream` semantics on modern JDKs. When
`DefaultObjectInputFilter` is absent (it only exists in the packaged
multi-release JAR), the helper falls back to
`FilteredObjectInputStream` on any Java version.

`SerializationTestHelper` in `log4j-1.2-api` now delegates to
`SerialUtil`, so its `org.apache.log4j.*` extras are honored on all
Java versions as well.

Part of the hardening series from #4168.

Assisted-By: Claude Fable 5 <[email protected]>
@ppkarwasz
ppkarwasz force-pushed the feat/2.x/serial-util-java9-filter branch from 513e55a to c245cf5 Compare August 31, 2026 21:21
@ppkarwasz
ppkarwasz changed the base branch from 2.x to feat/2.x/filtered-stream-reject-proxies August 31, 2026 21:23
@ramanathan1504

Copy link
Copy Markdown
Contributor

I checked the Java 9+ branch with a packaged log4j-api jar. Config.createFilter returns UNDECIDED for names it does not list, so the default allowlist still runs after it. java.io.File is rejected with no extras and allowed when passed as one. Arrays of it too.

Nothing tests it though. On 2.x today SerialUtil.getObjectInputStream returns a plain ObjectInputStream on JDK 17 and reads a java.io.File back fine. One assertThrows(IOException.class, ...) in log4j-api-test fails before this change and passes after, on Java 8 and Java 9+ both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants