Skip to content

Prevent insecure deserialization (CWE-502) in ZookeeperDistributedQueue#48

Open
devin-ai-integration[bot] wants to merge 1 commit into
develop-7.0.xfrom
devin/1782167711-fix-zk-queue-insecure-deserialization
Open

Prevent insecure deserialization (CWE-502) in ZookeeperDistributedQueue#48
devin-ai-integration[bot] wants to merge 1 commit into
develop-7.0.xfrom
devin/1782167711-fix-zk-queue-insecure-deserialization

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 22, 2026

Copy link
Copy Markdown

Fixing insecure deserialization (CWE-502) in ZookeeperDistributedQueue

ZookeeperDistributedQueue.deserialize() previously called ObjectInputStream.readObject() on bytes read from Zookeeper with no class filtering. An attacker able to influence data stored in Zookeeper could plant a serialized gadget chain and achieve Remote Code Execution.

A Brief Overview

This restricts which classes may be reconstructed during deserialization to an explicit allowlist, so unexpected/gadget classes are rejected before they can be instantiated.

  • New SecureObjectInputStream (an ObjectInputStream subclass) overrides resolveClass() to reject any class not on an allowlist and overrides resolveProxyClass() to reject all dynamic proxies (a common gadget vector). Array types are unwrapped to their component type before matching; primitive components are always allowed.
  • ZookeeperDistributedQueue.deserialize() now uses SecureObjectInputStream instead of a raw ObjectInputStream. Serialization is unchanged.
  • The allowlist is configurable per-queue via getDeserializationAllowlist() / setDeserializationAllowlist(List<String>) for applications that store custom serializable element types. The default covers boxed primitives, String, standard collections (java.util.*), java.time.*, java.math.*, and org.broadleafcommerce.*.

Allowlist pattern syntax: an exact FQCN (java.lang.Integer) or a package prefix ending in .* (java.util.*, matching the package and sub-packages).

protected Object deserialize(byte[] bytes) {
    ...
    ois = new SecureObjectInputStream(bais, getDeserializationAllowlist());
    return ois.readObject();  // non-allowlisted classes -> InvalidClassException
}

Tests

Added ZookeeperDistributedQueueDeserializationTest (6 tests, all passing) covering: allowlisted scalar/collection round-trips, rejection of a non-allowlisted serializable class (java.io.File) and array thereof, and honoring a custom allowlist.

Run: mvn -pl core/broadleaf-framework -am test -Dtest=ZookeeperDistributedQueueDeserializationTest -Dsurefire.failIfNoSpecifiedTests=false

Add Labels to the right panel: Security, Severity: critical, Status: ready-for-code-review

Additional context

The configurable allowlist means existing apps that place custom types on the queue may need to register their packages via setDeserializationAllowlist(...); otherwise behavior is unchanged for the standard types Broadleaf stores.

Link to Devin session: https://app.devin.ai/sessions/c14f970fa42d4e58a91bfe0882669e3c


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Open in Devin Review (Staging)

…edQueue

Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

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.

0 participants