CAMEL-23609: Tighten in-code ObjectInputFilter defaults with JEP-290 graph-shape limits#23523
Conversation
…graph-shape limits
Adds maxdepth=20;maxrefs=10000;maxbytes=10485760 to the in-code default
ObjectInputFilter used by the components that perform Java deserialization
through a real ObjectInputStream:
- camel-infinispan (DefaultExchangeHolderUtils)
- camel-mina (MinaConverter)
- camel-netty (NettyConverter)
- camel-netty-http (NettyHttpHelper)
- camel-vertx-http (VertxHttpHelper)
- camel-leveldb (LevelDBAggregationRepository.deserializationFilter)
- camel-cassandraql (CassandraAggregationRepository.deserializationFilter)
- camel-consul (ConsulRegistry.deserializationFilter)
- camel-sql (JdbcAggregationRepository.deserializationFilter)
The class allowlist is unchanged; only structural JEP-290 clauses are added.
Operators retain their existing overrides:
- JVM-wide -Djdk.serialFilter takes precedence over the Camel default.
- The configurable repositories and endpoint configurations expose a
deserializationFilter @UriParam that accepts a fully custom filter
string, including the structural clauses.
For the 4 configurable defaults a package-private DEFAULT_DESERIALIZATION_FILTER
constant is introduced so the value lives in one place and is referenced both
by the field initializer and by the @metadata defaultValue attribute, keeping
the catalog metadata, javadoc and field default in sync.
camel-jms and camel-sjms are intentionally NOT updated: they apply the filter
as a post-deserialization class check (after the JMS provider has already
decoded the payload), so JEP-290 graph-shape clauses are no-ops in those
sites. DoS hardening on the JMS path must be configured at the JMS provider
level (Artemis deserializationAllowList, ActiveMQ Classic SERIALIZABLE_PACKAGES)
or via -Djdk.serialFilter.
Adds a test at each affected site asserting the structural clauses are
present in the resolved default filter, and adds an upgrade-guide entry on
main for 4.21 with the override paths.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Andrea Cosentino <ancosen@gmail.com>
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
gnodet
left a comment
There was a problem hiding this comment.
Excellent security hardening. Adding JEP-290 graph-shape limits (maxdepth=20;maxrefs=10000;maxbytes=10485760) to the default ObjectInputFilter across all 9 deserialization sites is a solid defense-in-depth measure against deserialization attacks that exploit deeply nested or excessively large object graphs.
The limits are applied consistently across camel-infinispan, camel-mina, camel-netty, camel-netty-http, camel-vertx-http, camel-leveldb, camel-cassandraql, camel-consul, and camel-sql. The upgrade guide is thorough, documenting override paths for users who need different limits.
This follows the pattern of prior CVE fixes (CVE-2024-22369 et al.) that hardened these same sites, now adding the complementary graph-shape constraints.
LGTM.
Fully automatic review from Claude Code
Summary
Follow-up to the
CAMEL-23297/CAMEL-23319/CAMEL-23321/CAMEL-23322/CAMEL-23324/CAMEL-23372series. The in-code defaultObjectInputFiltershipped by the components below now also carries JEP-290 graph-shape limits (maxdepth=20,maxrefs=10000,maxbytes=10485760) in addition to the existing class allowlist. The class allowlist is unchanged.Affected sites (9):
DefaultExchangeHolderUtils.javaMinaConverter.javaNettyConverter.javaNettyHttpHelper.javaVertxHttpHelper.javaLevelDBAggregationRepository.deserializationFilterCassandraAggregationRepository.deserializationFilterConsulRegistry.deserializationFilterJdbcAggregationRepository.deserializationFilterFor the 4 configurable defaults a package-private
DEFAULT_DESERIALIZATION_FILTERconstant is introduced so the value lives in one place and is referenced both by the field initializer and the@Metadata(defaultValue = ...)attribute. This keeps the catalog metadata JSONs, the javadoc and the field default in sync.Why graph-shape clauses and not just the class allowlist?
The current class allowlist (
!java.net.**;java.**;javax.**;org.apache.camel.**;!*) blocks gadget-chain RCE but does not bound how deep, how wide or how large an inbound serialized graph can be. Addingmaxdepth/maxrefs/maxbytesis the standard JEP-290 way to bound CPU/memory cost duringreadObject()and is a pure defense-in-depth improvement.Operator overrides preserved
-Djdk.serialFilterstill takes precedence over the Camel default in every site that ships one.LevelDBAggregationRepository,JdbcAggregationRepository,CassandraAggregationRepository,ConsulRegistry, netty-http / vertx-http endpoint configuration) already expose adeserializationFilter@UriParamaccepting a fully custom filter string, including structural clauses or none at all.Intentionally not changed: camel-jms / camel-sjms
Both apply their filter as a post-deserialization class check (after the JMS provider has already decoded the payload via its own
ObjectInputStream). Graph-shape limits are therefore no-ops in those sites and have not been added. DoS hardening on the JMS path must be configured at the JMS provider level (ArtemisdeserializationAllowList, ActiveMQ ClassicSERIALIZABLE_PACKAGES) or via-Djdk.serialFilter. The upgrade-guide entry calls this out explicitly.Tests
A small
DefaultFilterTest(or equivalent test method added to an existing class) at each of the 9 sites asserts that the resolved default filter containsmaxdepth=,maxrefs=andmaxbytes=. For the 4 configurable sites the test additionally constructs the repository and assertsgetDeserializationFilter()returns the sameDEFAULT_DESERIALIZATION_FILTERconstant.Upgrade guide
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adocgains a "Tightened default ObjectInputFilter across deserialization sites - potential breaking change" entry listing the affected components, the new defaults and the override paths, and noting the JMS exclusion.Test plan
mvn -B -DskipITs teston each of the 9 changed modules - all pass locally. (One unrelatedNettyTCPSyncUDSTestfailure on local FS with long UDS path; not related to this change.)mvn -B clean install -DskipTestssucceeds; downstream catalog mirrors incatalog/camel-catalog/.../beans/regenerated and committed.Notes for reviewers
The new structural defaults are conservative (
maxdepth=20,maxrefs=10000,maxbytes=10MB). They are intended to comfortably handle aDefaultExchangeHoldercarrying a typical Exchange payload but to reject extremely deep / very wide / multi-megabyte graphs. If a route legitimately needs to deserialize a graph that exceeds any of these, the per-endpointdeserializationFilteroption or-Djdk.serialFilteris the existing escape hatch.Claude Code on behalf of Andrea Cosentino