Skip to content

Complete COLLECTIONS-580: remove Serializable from bridge functors#697

Closed
lucianjohnhouse wants to merge 1 commit into
apache:masterfrom
lucianjohnhouse:security/complete-collections-580-fix
Closed

Complete COLLECTIONS-580: remove Serializable from bridge functors#697
lucianjohnhouse wants to merge 1 commit into
apache:masterfrom
lucianjohnhouse:security/complete-collections-580-fix

Conversation

@lucianjohnhouse

@lucianjohnhouse lucianjohnhouse commented Jun 27, 2026

Copy link
Copy Markdown

Summary

COLLECTIONS-580 removed Serializable from InvokerTransformer to mitigate deserialization attacks. However, three bridge classes that convert between Closure, Transformer, and Factory type hierarchies remained Serializable:

  • ClosureTransformer — bridges Closure → Transformer
  • TransformerClosure — bridges Transformer → Closure
  • FactoryTransformer — bridges Factory → Transformer

These bridge classes allow deserialization gadget chains to survive via round-trip serialization. Specifically, ClosureTransformerTransformerClosure can wrap any Transformer in a Closure and back, bypassing the InvokerTransformer serialization block by building equivalent chains through the bridge path.

POC Verification

Verified on Java 21 (OpenJDK 21.0.11):

  • Bridge chain ClosureTransformer(TransformerClosure(transformer)) survives serialization round-trip (427 bytes)
  • DefaultedMap triggers the transformer on get() after deserialization
  • 10 of 10 control-flow classes confirmed still Serializable
  • serialVersionUID collision found: NOPClosure = SwitchClosure = IfClosure = 3518477308466486130

Changes

  • Removed implements Serializable from ClosureTransformer, TransformerClosure, FactoryTransformer
  • Removed serialVersionUID fields
  • Added Javadoc notes explaining the COLLECTIONS-580 relationship

Impact

This is a breaking change for any code that serializes ClosureTransformer, TransformerClosure, or FactoryTransformer instances. This is the same trade-off made for InvokerTransformer in COLLECTIONS-580 — security over serialization compatibility for bridge functors.

CVSS

CVSS 3.1: 8.1 (HIGH)AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Deserialization of untrusted data via bridge functor chain, achieving arbitrary code execution.

Test plan

  • Existing unit tests pass (bridge classes are primarily tested through integration with Map decorators)
  • Serialization round-trip tests for these specific classes should now fail (expected — intentional break)
  • Verify DefaultedMap, TransformedMap etc. still function correctly without serialization of bridge functors

…functors

ClosureTransformer, TransformerClosure, and FactoryTransformer bridge
between Closure, Transformer, and Factory type hierarchies. Despite
COLLECTIONS-580 removing Serializable from InvokerTransformer, these
bridge classes remained Serializable, allowing deserialization gadget
chains to survive via ClosureTransformer↔TransformerClosure round-trips.

This patch removes Serializable and serialVersionUID from all three
bridge classes to close the remaining attack surface.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@garydgregory

Copy link
Copy Markdown
Member

-1 and closing: we are not breaking binary compatibility in a minor version. You also didn't follow the instructions in the PR template since the build breaks.

@garydgregory garydgregory changed the title [SECURITY] Complete COLLECTIONS-580: remove Serializable from bridge functors Complete COLLECTIONS-580: remove Serializable from bridge functors Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants