dotCMS / dotCMS/core

Harden Redis cache codec (DotObjectCodec) against unsafe Java deserialization

Open
#36,674 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

dotCMS : Security OKR : Customer Support Team : Maintenance Type : Task
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Description

DotObjectCodec (dotCMS/src/main/java/com/dotcms/cache/lettuce/DotObjectCodec.java) serializes and deserializes every object stored in a Redis-backed cache region using plain Java ObjectOutputStream / ObjectInputStream (wrapped with GZIP by MasterReplicaLettuceClient). Native Java deserialization is a well-known remote-code-execution surface: an actor who can write arbitrary bytes into the Redis instance backing the cache could deliver a crafted serialized payload (e.g. a ysoserial-style gadget chain) that executes during readObject() on the dotCMS side.

This is an infrastructure trust-boundary concern, not something reachable from ordinary end-user input — exploitation requires write access to the shared Redis used as a cache provider. It is therefore lower urgency than a directly user-facing vulnerability. However, because Redis is often a shared or managed service, defense-in-depth is warranted.

Context: This was surfaced while fixing #34435 (Portlet cache NullPointerException under the Redis provider). That issue is a distinct transient-field bug and is being fixed separately. This issue tracks only the deserialization-codec hardening.

Relevant files:

File Concern
dotCMS/src/main/java/com/dotcms/cache/lettuce/DotObjectCodec.java Builds the ObjectInputStream (decodeValue) with no deserialization allow-list
dotCMS/src/main/java/com/dotcms/cache/lettuce/MasterReplicaLettuceClient.java Wires DotObjectCodec + GZIP as the default codec for all Redis-cached objects
dotCMS/src/main/java/com/dotcms/cache/lettuce/RedisCache.java get() / extractObject() — deserialization entry point; failures currently logged at debug only

Acceptance Criteria

  • To be refined — quick draft; details to be added later.
  • Apply a JDK ObjectInputFilter (JEP 290) allow-list to the ObjectInputStream in DotObjectCodec, restricting deserialization to the set of dotCMS-cacheable types plus safe JDK collection/wrapper classes.
  • Payloads that fail the filter are rejected (treated as a cache miss) and logged at warn/error — never at debug only.
  • Evaluate whether a safer serialization format (or per-region codec) is feasible for cache payloads.

dotCMS Version

Current Evergreen 26.07.13-1

Priority

Medium

Additional Context

  • Native Java deserialization gadget chains are a standard RCE vector; the standard mitigation is a JEP 290 ObjectInputFilter allow-list rather than unrestricted readObject().
  • Related: #34435 (Portlet cache NPE under Redis — the transient initParams fix; separate PR).
  • The diagnostics gap noted in #34435 research applies here too: RedisCache.get() swallows deserialization exceptions at debug level, so a malformed/rejected payload is currently near-invisible in logs.

Links

Freshdesk ticket of the related issue: https://helpdesk.dotcms.com/a/tickets/34992

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with dotCMS/src/main/java/com/dotcms/cache/lettuce/DotObjectCodec.java, especially decodeValue and its ObjectInputStream construction. Trace the codec and GZIP wiring in MasterReplicaLettuceClient.java, then follow RedisCache.java get()/extractObject() to understand failure handling. Done means rejected payloads are filtered and logged above debug, the cache behavior is covered, and safer serialization or per-region codec feasibility is assessed.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, redis
Domain
backend, infrastructure, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.