This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new ab4e81cd2ccd CAMEL-23609: Tighten in-code ObjectInputFilter defaults
with JEP-290 graph-shape limits (#23523)
ab4e81cd2ccd is described below
commit ab4e81cd2ccd1b64826960a106f4033af442b5f8
Author: Andrea Cosentino <[email protected]>
AuthorDate: Wed May 27 09:21:09 2026 +0200
CAMEL-23609: Tighten in-code ObjectInputFilter defaults with JEP-290
graph-shape limits (#23523)
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.
---
.../catalog/beans/JdbcAggregationRepository.json | 2 +-
.../beans/LevelDBAggregationRepository.json | 2 +-
.../cassandra/CassandraAggregationRepository.java | 15 ++++++--
...ndraAggregationRepositoryDefaultFilterTest.java | 39 +++++++++++++++++++
.../camel/component/consul/ConsulRegistry.java | 12 +++++-
.../consul/ConsulRegistryDefaultFilterTest.java | 32 +++++++++++++++
.../protostream/DefaultExchangeHolderUtils.java | 6 ++-
.../DefaultExchangeHolderUtilsTest.java | 9 +++++
.../camel/bean/LevelDBAggregationRepository.json | 2 +-
.../leveldb/LevelDBAggregationRepository.java | 16 +++++---
.../camel/component/leveldb/LevelDBSerializer.java | 2 +-
...elDBAggregationRepositoryDefaultFilterTest.java | 39 +++++++++++++++++++
.../apache/camel/component/mina/MinaConverter.java | 6 ++-
.../mina/MinaConverterDefaultFilterTest.java | 32 +++++++++++++++
.../component/netty/http/NettyHttpHelper.java | 7 ++--
.../NettyHttpHelperDeserializationFilterTest.java | 9 +++++
.../camel/component/netty/NettyConverter.java | 6 ++-
.../netty/NettyConverterDefaultFilterTest.java | 32 +++++++++++++++
.../camel/bean/JdbcAggregationRepository.json | 2 +-
.../aggregate/jdbc/JdbcAggregationRepository.java | 16 ++++++--
...JdbcAggregationRepositoryDefaultFilterTest.java | 39 +++++++++++++++++++
.../component/vertx/http/VertxHttpHelper.java | 7 ++--
.../VertxHttpHelperDeserializationFilterTest.java | 9 +++++
.../ROOT/pages/camel-4x-upgrade-guide-4_21.adoc | 45 ++++++++++++++++++++++
24 files changed, 355 insertions(+), 31 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcAggregationRepository.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcAggregationRepository.json
index d12cdf42f4b1..3c91c157fd56 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcAggregationRepository.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcAggregationRepository.json
@@ -10,7 +10,7 @@
"groupId": "org.apache.camel",
"artifactId": "camel-sql",
"version": "4.21.0-SNAPSHOT",
- "properties": { "dataSource": { "index": 0, "kind": "property",
"displayName": "Data Source", "required": true, "type": "object", "javaType":
"javax.sql.DataSource", "deprecated": false, "autowired": false, "secret":
false, "description": "The DataSource to use for connecting to the database" },
"transactionManager": { "index": 1, "kind": "property", "displayName":
"Transaction Manager", "required": true, "type": "object", "javaType":
"org.springframework.transaction.PlatformTransact [...]
+ "properties": { "dataSource": { "index": 0, "kind": "property",
"displayName": "Data Source", "required": true, "type": "object", "javaType":
"javax.sql.DataSource", "deprecated": false, "autowired": false, "secret":
false, "description": "The DataSource to use for connecting to the database" },
"transactionManager": { "index": 1, "kind": "property", "displayName":
"Transaction Manager", "required": true, "type": "object", "javaType":
"org.springframework.transaction.PlatformTransact [...]
}
}
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LevelDBAggregationRepository.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LevelDBAggregationRepository.json
index 015afbc5e1b7..d899acc4af65 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LevelDBAggregationRepository.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LevelDBAggregationRepository.json
@@ -10,7 +10,7 @@
"groupId": "org.apache.camel",
"artifactId": "camel-leveldb",
"version": "4.21.0-SNAPSHOT",
- "properties": { "persistentFileName": { "index": 0, "kind": "property",
"displayName": "Persistent File Name", "required": true, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "Name of file to use for storing data" },
"repositoryName": { "index": 1, "kind": "property", "displayName": "Repository
Name", "required": true, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, [...]
+ "properties": { "persistentFileName": { "index": 0, "kind": "property",
"displayName": "Persistent File Name", "required": true, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "Name of file to use for storing data" },
"repositoryName": { "index": 1, "kind": "property", "displayName": "Repository
Name", "required": true, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, [...]
}
}
diff --git
a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepository.java
b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepository.java
index 666a5ac91ad9..f3c2b9a7d913 100644
---
a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepository.java
+++
b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepository.java
@@ -115,14 +115,23 @@ public class CassandraAggregationRepository extends
ServiceSupport implements Re
description = "Whether headers on the Exchange that are Java
objects and Serializable should be included and saved to the repository")
private boolean allowSerializedHeaders;
+ /**
+ * Default deserialization filter. Denies {@code java.net.**} and
otherwise allows {@code java.**} and
+ * {@code org.apache.camel.**}; applies JEP-290 graph-shape limits ({@code
maxdepth}, {@code maxrefs},
+ * {@code maxbytes}) as defense-in-depth against resource-exhaustion
payloads.
+ */
+ static final String DEFAULT_DESERIALIZATION_FILTER
+ =
"!java.net.**;java.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*";
+
/**
* Sets a deserialization filter while reading Object from Aggregation
Repository. By default the filter denies
* {@code java.net.**} (to avoid classes whose hash/equals methods perform
network I/O) and otherwise allows all
* java packages and subpackages and all org.apache.camel packages and
subpackages, while the remaining will be
- * blacklisted and not deserialized. This parameter should be customized
if you're using classes you trust to be
- * deserialized.
+ * blacklisted and not deserialized. It also applies JEP-290 graph-shape
limits ({@code maxdepth}, {@code maxrefs},
+ * {@code maxbytes}) as defense-in-depth against resource-exhaustion
payloads. This parameter should be customized
+ * if you're using classes you trust to be deserialized.
*/
- private String deserializationFilter =
"!java.net.**;java.**;org.apache.camel.**;!*";
+ private String deserializationFilter = DEFAULT_DESERIALIZATION_FILTER;
public CassandraAggregationRepository() {
}
diff --git
a/components/camel-cassandraql/src/test/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepositoryDefaultFilterTest.java
b/components/camel-cassandraql/src/test/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepositoryDefaultFilterTest.java
new file mode 100644
index 000000000000..d48a2824b982
--- /dev/null
+++
b/components/camel-cassandraql/src/test/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepositoryDefaultFilterTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor.aggregate.cassandra;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class CassandraAggregationRepositoryDefaultFilterTest {
+
+ @Test
+ public void testDefaultFilterContainsGraphShapeLimits() {
+ String filter =
CassandraAggregationRepository.DEFAULT_DESERIALIZATION_FILTER;
+ assertTrue(filter.contains("maxdepth="), "Expected maxdepth in filter:
" + filter);
+ assertTrue(filter.contains("maxrefs="), "Expected maxrefs in filter: "
+ filter);
+ assertTrue(filter.contains("maxbytes="), "Expected maxbytes in filter:
" + filter);
+ }
+
+ @Test
+ public void testNewInstanceUsesDefaultFilter() {
+ CassandraAggregationRepository repo = new
CassandraAggregationRepository();
+
assertEquals(CassandraAggregationRepository.DEFAULT_DESERIALIZATION_FILTER,
repo.getDeserializationFilter());
+ }
+}
diff --git
a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulRegistry.java
b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulRegistry.java
index b80b0b6ee3aa..aeabdfdc9d0e 100644
---
a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulRegistry.java
+++
b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulRegistry.java
@@ -49,11 +49,19 @@ import
org.kiwiproject.consul.model.session.SessionCreatedResponse;
*/
public class ConsulRegistry implements Registry {
+ /**
+ * Default deserialization filter. Denies {@code java.net.**} and
otherwise allows {@code java.**} and
+ * {@code org.apache.camel.**}; applies JEP-290 graph-shape limits ({@code
maxdepth}, {@code maxrefs},
+ * {@code maxbytes}) as defense-in-depth against resource-exhaustion
payloads.
+ */
+ static final String DEFAULT_DESERIALIZATION_FILTER
+ =
"!java.net.**;java.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*";
+
private String hostname = "localhost";
private int port = 8500;
private Consul consul;
private KeyValueClient kvClient;
- private String deserializationFilter =
"!java.net.**;java.**;org.apache.camel.**;!*";
+ private String deserializationFilter = DEFAULT_DESERIALIZATION_FILTER;
/* constructor with default port */
public ConsulRegistry(String hostname) {
@@ -331,7 +339,7 @@ public class ConsulRegistry implements Registry {
*
* @param bytes the byte array to deserialize from
* @param deserializationFilter the deserialization filter to apply
(e.g.
- *
"!java.net.**;java.**;org.apache.camel.**;!*")
+ *
"!java.net.**;java.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*")
* @return an {@link Object} deserialized from
the given byte array
*/
static Object deserialize(byte[] bytes, String deserializationFilter) {
diff --git
a/components/camel-consul/src/test/java/org/apache/camel/component/consul/ConsulRegistryDefaultFilterTest.java
b/components/camel-consul/src/test/java/org/apache/camel/component/consul/ConsulRegistryDefaultFilterTest.java
new file mode 100644
index 000000000000..8f3be504462b
--- /dev/null
+++
b/components/camel-consul/src/test/java/org/apache/camel/component/consul/ConsulRegistryDefaultFilterTest.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.consul;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ConsulRegistryDefaultFilterTest {
+
+ @Test
+ public void testDefaultFilterContainsGraphShapeLimits() {
+ String filter = ConsulRegistry.DEFAULT_DESERIALIZATION_FILTER;
+ assertTrue(filter.contains("maxdepth="), "Expected maxdepth in filter:
" + filter);
+ assertTrue(filter.contains("maxrefs="), "Expected maxrefs in filter: "
+ filter);
+ assertTrue(filter.contains("maxbytes="), "Expected maxbytes in filter:
" + filter);
+ }
+}
diff --git
a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/protostream/DefaultExchangeHolderUtils.java
b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/protostream/DefaultExchangeHolderUtils.java
index 9ca1e8a7825e..701fc4c8a2cf 100644
---
a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/protostream/DefaultExchangeHolderUtils.java
+++
b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/protostream/DefaultExchangeHolderUtils.java
@@ -35,10 +35,12 @@ final class DefaultExchangeHolderUtils {
/**
* Default deserialization filter that restricts which classes can be
deserialized. Allows standard Java types and
- * Apache Camel types. Can be overridden via the JVM system property
{@code jdk.serialFilter}.
+ * Apache Camel types, denies {@code java.net.**}, and applies JEP-290
graph-shape limits ({@code maxdepth},
+ * {@code maxrefs}, {@code maxbytes}) as defense-in-depth against
resource-exhaustion payloads. Can be overridden
+ * via the JVM system property {@code jdk.serialFilter}.
*/
static final String DEFAULT_DESERIALIZATION_FILTER
- = "!java.net.**;java.**;javax.**;org.apache.camel.**;!*";
+ =
"!java.net.**;java.**;javax.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*";
private static final Logger LOG =
LoggerFactory.getLogger(DefaultExchangeHolderUtils.class);
diff --git
a/components/camel-infinispan/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/remote/protostream/DefaultExchangeHolderUtilsTest.java
b/components/camel-infinispan/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/remote/protostream/DefaultExchangeHolderUtilsTest.java
index 8019794baa4e..c065bedcdb89 100644
---
a/components/camel-infinispan/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/remote/protostream/DefaultExchangeHolderUtilsTest.java
+++
b/components/camel-infinispan/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/remote/protostream/DefaultExchangeHolderUtilsTest.java
@@ -29,9 +29,18 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class DefaultExchangeHolderUtilsTest {
+ @Test
+ public void testDefaultFilterContainsGraphShapeLimits() {
+ String filter =
DefaultExchangeHolderUtils.DEFAULT_DESERIALIZATION_FILTER;
+ assertTrue(filter.contains("maxdepth="), "Expected maxdepth in filter:
" + filter);
+ assertTrue(filter.contains("maxrefs="), "Expected maxrefs in filter: "
+ filter);
+ assertTrue(filter.contains("maxbytes="), "Expected maxbytes in filter:
" + filter);
+ }
+
@Test
public void testDeserializeAcceptsDefaultExchangeHolder() {
DefaultCamelContext context = new DefaultCamelContext();
diff --git
a/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean/LevelDBAggregationRepository.json
b/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean/LevelDBAggregationRepository.json
index 015afbc5e1b7..d899acc4af65 100644
---
a/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean/LevelDBAggregationRepository.json
+++
b/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean/LevelDBAggregationRepository.json
@@ -10,7 +10,7 @@
"groupId": "org.apache.camel",
"artifactId": "camel-leveldb",
"version": "4.21.0-SNAPSHOT",
- "properties": { "persistentFileName": { "index": 0, "kind": "property",
"displayName": "Persistent File Name", "required": true, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "Name of file to use for storing data" },
"repositoryName": { "index": 1, "kind": "property", "displayName": "Repository
Name", "required": true, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, [...]
+ "properties": { "persistentFileName": { "index": 0, "kind": "property",
"displayName": "Persistent File Name", "required": true, "type": "string",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "description": "Name of file to use for storing data" },
"repositoryName": { "index": 1, "kind": "property", "displayName": "Repository
Name", "required": true, "type": "string", "javaType": "java.lang.String",
"deprecated": false, "autowired": false, [...]
}
}
diff --git
a/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBAggregationRepository.java
b/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBAggregationRepository.java
index 6f281c94ac5a..bfb00c0b8382 100644
---
a/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBAggregationRepository.java
+++
b/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBAggregationRepository.java
@@ -80,19 +80,23 @@ public class LevelDBAggregationRepository extends
ServiceSupport implements Reco
private LevelDBSerializer serializer;
/**
- * Sets a deserialization filter while reading Object from Aggregation
Repository. By default the filter will allow
- * all java packages and subpackages and all org.apache.camel packages and
subpackages, while the remaining will be
- * blacklisted and not deserialized. This parameter should be customized
if you're using classes you trust to be
- * deserialized.
+ * Default deserialization filter. Denies {@code java.net.**} and
otherwise allows {@code java.**} and
+ * {@code org.apache.camel.**}; applies JEP-290 graph-shape limits ({@code
maxdepth}, {@code maxrefs},
+ * {@code maxbytes}) as defense-in-depth against resource-exhaustion
payloads.
*/
+ static final String DEFAULT_DESERIALIZATION_FILTER
+ =
"!java.net.**;java.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*";
+
@Metadata(label = "advanced",
description = "Sets a deserialization filter while reading
Object from Aggregation Repository."
+ " By default the filter denies java.net.** (to
avoid classes whose hash/equals methods perform"
+ " network I/O) and otherwise allows all java
packages and subpackages and all org.apache.camel"
+ " packages and subpackages, while the remaining
will be blacklisted and not deserialized."
+ + " It also applies JEP-290 graph-shape limits
(maxdepth, maxrefs, maxbytes) as defense-in-depth"
+ + " against resource-exhaustion payloads."
+ " This parameter should be customized if you're
using classes you trust to be deserialized.",
- defaultValue = "!java.net.**;java.**;org.apache.camel.**;!*")
- private String deserializationFilter =
"!java.net.**;java.**;org.apache.camel.**;!*";
+ defaultValue = DEFAULT_DESERIALIZATION_FILTER)
+ private String deserializationFilter = DEFAULT_DESERIALIZATION_FILTER;
/**
* Creates an aggregation repository
diff --git
a/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBSerializer.java
b/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBSerializer.java
index 95b4b1c8b7da..faafd8f930c8 100644
---
a/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBSerializer.java
+++
b/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBSerializer.java
@@ -39,7 +39,7 @@ public interface LevelDBSerializer {
* @param camelContext the CamelContext
* @param buffer the byte buffer containing serialized
exchange data
* @param deserializationFilter the deserialization filter pattern to
apply (e.g.,
- *
"!java.net.**;java.**;org.apache.camel.**;!*")
+ *
"!java.net.**;java.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*")
* @return the deserialized Exchange
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a class cannot be found during
deserialization
diff --git
a/components/camel-leveldb/src/test/java/org/apache/camel/component/leveldb/LevelDBAggregationRepositoryDefaultFilterTest.java
b/components/camel-leveldb/src/test/java/org/apache/camel/component/leveldb/LevelDBAggregationRepositoryDefaultFilterTest.java
new file mode 100644
index 000000000000..41ef155b230e
--- /dev/null
+++
b/components/camel-leveldb/src/test/java/org/apache/camel/component/leveldb/LevelDBAggregationRepositoryDefaultFilterTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.leveldb;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class LevelDBAggregationRepositoryDefaultFilterTest {
+
+ @Test
+ public void testDefaultFilterContainsGraphShapeLimits() {
+ String filter =
LevelDBAggregationRepository.DEFAULT_DESERIALIZATION_FILTER;
+ assertTrue(filter.contains("maxdepth="), "Expected maxdepth in filter:
" + filter);
+ assertTrue(filter.contains("maxrefs="), "Expected maxrefs in filter: "
+ filter);
+ assertTrue(filter.contains("maxbytes="), "Expected maxbytes in filter:
" + filter);
+ }
+
+ @Test
+ public void testNewInstanceUsesDefaultFilter() {
+ LevelDBAggregationRepository repo = new LevelDBAggregationRepository();
+
assertEquals(LevelDBAggregationRepository.DEFAULT_DESERIALIZATION_FILTER,
repo.getDeserializationFilter());
+ }
+}
diff --git
a/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaConverter.java
b/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaConverter.java
index 2b9916aa5924..b721ce8e1cfa 100644
---
a/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaConverter.java
+++
b/components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaConverter.java
@@ -38,10 +38,12 @@ public final class MinaConverter {
/**
* Default deserialization filter that restricts which classes can be
deserialized. Allows standard Java types and
- * Apache Camel types. Can be overridden via the JVM system property
{@code jdk.serialFilter}.
+ * Apache Camel types, denies {@code java.net.**}, and applies JEP-290
graph-shape limits ({@code maxdepth},
+ * {@code maxrefs}, {@code maxbytes}) as defense-in-depth against
resource-exhaustion payloads. Can be overridden
+ * via the JVM system property {@code jdk.serialFilter}.
*/
static final String DEFAULT_DESERIALIZATION_FILTER
- = "!java.net.**;java.**;javax.**;org.apache.camel.**;!*";
+ =
"!java.net.**;java.**;javax.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*";
private MinaConverter() {
//Utility Class
diff --git
a/components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaConverterDefaultFilterTest.java
b/components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaConverterDefaultFilterTest.java
new file mode 100644
index 000000000000..bcb2380de3f3
--- /dev/null
+++
b/components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaConverterDefaultFilterTest.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.mina;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class MinaConverterDefaultFilterTest {
+
+ @Test
+ public void testDefaultFilterContainsGraphShapeLimits() {
+ String filter = MinaConverter.DEFAULT_DESERIALIZATION_FILTER;
+ assertTrue(filter.contains("maxdepth="), "Expected maxdepth in filter:
" + filter);
+ assertTrue(filter.contains("maxrefs="), "Expected maxrefs in filter: "
+ filter);
+ assertTrue(filter.contains("maxbytes="), "Expected maxbytes in filter:
" + filter);
+ }
+}
diff --git
a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
index cc4f5c161201..fbbcac910f5f 100644
---
a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
+++
b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java
@@ -44,13 +44,14 @@ public final class NettyHttpHelper {
/**
* Default {@link ObjectInputFilter} pattern applied when deserializing
Java objects from HTTP responses with
- * Content-Type {@code application/x-java-serialized-object}. Allows
standard Java types and Apache Camel types and
- * rejects everything else. Can be overridden per-endpoint via
+ * Content-Type {@code application/x-java-serialized-object}. Allows
standard Java types and Apache Camel types,
+ * denies {@code java.net.**}, and applies JEP-290 graph-shape limits
({@code maxdepth}, {@code maxrefs},
+ * {@code maxbytes}) as defense-in-depth against resource-exhaustion
payloads. Can be overridden per-endpoint via
* {@link NettyHttpConfiguration#setDeserializationFilter(String)} or
globally via the JVM system property
* {@code jdk.serialFilter}.
*/
static final String DEFAULT_DESERIALIZATION_FILTER
- = "!java.net.**;java.**;javax.**;org.apache.camel.**;!*";
+ =
"!java.net.**;java.**;javax.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*";
private static final Logger LOG =
LoggerFactory.getLogger(NettyHttpHelper.class);
diff --git
a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpHelperDeserializationFilterTest.java
b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpHelperDeserializationFilterTest.java
index 9a48d7ce8dd2..b1dda73bdd48 100644
---
a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpHelperDeserializationFilterTest.java
+++
b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpHelperDeserializationFilterTest.java
@@ -29,9 +29,18 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class NettyHttpHelperDeserializationFilterTest {
+ @Test
+ public void testDefaultFilterContainsGraphShapeLimits() {
+ String filter = NettyHttpHelper.DEFAULT_DESERIALIZATION_FILTER;
+ assertTrue(filter.contains("maxdepth="), "Expected maxdepth in filter:
" + filter);
+ assertTrue(filter.contains("maxrefs="), "Expected maxrefs in filter: "
+ filter);
+ assertTrue(filter.contains("maxbytes="), "Expected maxbytes in filter:
" + filter);
+ }
+
@Test
public void testDeserializeAllowlistedType() throws Exception {
InputStream is = serialize("hello");
diff --git
a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConverter.java
b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConverter.java
index 3837a43e3fed..9b817138efbf 100644
---
a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConverter.java
+++
b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConverter.java
@@ -47,10 +47,12 @@ public final class NettyConverter {
/**
* Default deserialization filter that restricts which classes can be
deserialized. Allows standard Java types and
- * Apache Camel types. Can be overridden via the JVM system property
{@code jdk.serialFilter}.
+ * Apache Camel types, denies {@code java.net.**}, and applies JEP-290
graph-shape limits ({@code maxdepth},
+ * {@code maxrefs}, {@code maxbytes}) as defense-in-depth against
resource-exhaustion payloads. Can be overridden
+ * via the JVM system property {@code jdk.serialFilter}.
*/
static final String DEFAULT_DESERIALIZATION_FILTER
- = "!java.net.**;java.**;javax.**;org.apache.camel.**;!*";
+ =
"!java.net.**;java.**;javax.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*";
private NettyConverter() {
//Utility Class
diff --git
a/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyConverterDefaultFilterTest.java
b/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyConverterDefaultFilterTest.java
new file mode 100644
index 000000000000..455b2121c815
--- /dev/null
+++
b/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyConverterDefaultFilterTest.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.netty;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class NettyConverterDefaultFilterTest {
+
+ @Test
+ public void testDefaultFilterContainsGraphShapeLimits() {
+ String filter = NettyConverter.DEFAULT_DESERIALIZATION_FILTER;
+ assertTrue(filter.contains("maxdepth="), "Expected maxdepth in filter:
" + filter);
+ assertTrue(filter.contains("maxrefs="), "Expected maxrefs in filter: "
+ filter);
+ assertTrue(filter.contains("maxbytes="), "Expected maxbytes in filter:
" + filter);
+ }
+}
diff --git
a/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcAggregationRepository.json
b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcAggregationRepository.json
index d12cdf42f4b1..3c91c157fd56 100644
---
a/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcAggregationRepository.json
+++
b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcAggregationRepository.json
@@ -10,7 +10,7 @@
"groupId": "org.apache.camel",
"artifactId": "camel-sql",
"version": "4.21.0-SNAPSHOT",
- "properties": { "dataSource": { "index": 0, "kind": "property",
"displayName": "Data Source", "required": true, "type": "object", "javaType":
"javax.sql.DataSource", "deprecated": false, "autowired": false, "secret":
false, "description": "The DataSource to use for connecting to the database" },
"transactionManager": { "index": 1, "kind": "property", "displayName":
"Transaction Manager", "required": true, "type": "object", "javaType":
"org.springframework.transaction.PlatformTransact [...]
+ "properties": { "dataSource": { "index": 0, "kind": "property",
"displayName": "Data Source", "required": true, "type": "object", "javaType":
"javax.sql.DataSource", "deprecated": false, "autowired": false, "secret":
false, "description": "The DataSource to use for connecting to the database" },
"transactionManager": { "index": 1, "kind": "property", "displayName":
"Transaction Manager", "required": true, "type": "object", "javaType":
"org.springframework.transaction.PlatformTransact [...]
}
}
diff --git
a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepository.java
b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepository.java
index adc23481f877..800ab575fba2 100644
---
a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepository.java
+++
b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepository.java
@@ -111,12 +111,22 @@ public class JdbcAggregationRepository extends
ServiceSupport
@Metadata(label = "advanced", security = "insecure:serialization",
description = "Whether headers on the Exchange that are Java
objects and Serializable should be included and saved to the repository")
private boolean allowSerializedHeaders;
- @Metadata(label = "security", defaultValue =
"!java.net.**;java.**;org.apache.camel.**;!*",
+ /**
+ * Default deserialization filter. Denies {@code java.net.**} and
otherwise allows {@code java.**} and
+ * {@code org.apache.camel.**}; applies JEP-290 graph-shape limits ({@code
maxdepth}, {@code maxrefs},
+ * {@code maxbytes}) as defense-in-depth against resource-exhaustion
payloads.
+ */
+ static final String DEFAULT_DESERIALIZATION_FILTER
+ =
"!java.net.**;java.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*";
+
+ @Metadata(label = "security", defaultValue =
DEFAULT_DESERIALIZATION_FILTER,
description = "Sets a deserialization filter while reading
Object from Aggregation Repository. By default the filter denies"
+ " java.net.** (to avoid classes whose
hash/equals methods perform network I/O) and otherwise allows all java"
+ " packages and subpackages and all
org.apache.camel packages and subpackages, while the remaining will be"
- + " blacklisted and not deserialized. This
parameter should be customized if you're using classes you trust to be
deserialized.")
- private String deserializationFilter =
"!java.net.**;java.**;org.apache.camel.**;!*";
+ + " blacklisted and not deserialized. It also
applies JEP-290 graph-shape limits (maxdepth, maxrefs, maxbytes)"
+ + " as defense-in-depth against
resource-exhaustion payloads. This parameter should be customized if you're"
+ + " using classes you trust to be deserialized.")
+ private String deserializationFilter = DEFAULT_DESERIALIZATION_FILTER;
@Metadata(label = "advanced",
description = "Mapper allowing different JDBC vendors to be
mapped with vendor specific error codes to an OptimisticLockingException")
private JdbcOptimisticLockingExceptionMapper
jdbcOptimisticLockingExceptionMapper
diff --git
a/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepositoryDefaultFilterTest.java
b/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepositoryDefaultFilterTest.java
new file mode 100644
index 000000000000..745d69bc01e8
--- /dev/null
+++
b/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepositoryDefaultFilterTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor.aggregate.jdbc;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class JdbcAggregationRepositoryDefaultFilterTest {
+
+ @Test
+ public void testDefaultFilterContainsGraphShapeLimits() {
+ String filter =
JdbcAggregationRepository.DEFAULT_DESERIALIZATION_FILTER;
+ assertTrue(filter.contains("maxdepth="), "Expected maxdepth in filter:
" + filter);
+ assertTrue(filter.contains("maxrefs="), "Expected maxrefs in filter: "
+ filter);
+ assertTrue(filter.contains("maxbytes="), "Expected maxbytes in filter:
" + filter);
+ }
+
+ @Test
+ public void testNewInstanceUsesDefaultFilter() {
+ JdbcAggregationRepository repo = new JdbcAggregationRepository();
+ assertEquals(JdbcAggregationRepository.DEFAULT_DESERIALIZATION_FILTER,
repo.getDeserializationFilter());
+ }
+}
diff --git
a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHelper.java
b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHelper.java
index dda45bad5d44..2ac0b5c76bba 100644
---
a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHelper.java
+++
b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpHelper.java
@@ -38,13 +38,14 @@ public final class VertxHttpHelper {
/**
* Default {@link ObjectInputFilter} pattern applied when deserializing
Java objects from HTTP responses with
- * Content-Type {@code application/x-java-serialized-object}. Allows
standard Java types and Apache Camel types and
- * rejects everything else. Can be overridden per-endpoint via
+ * Content-Type {@code application/x-java-serialized-object}. Allows
standard Java types and Apache Camel types,
+ * denies {@code java.net.**}, and applies JEP-290 graph-shape limits
({@code maxdepth}, {@code maxrefs},
+ * {@code maxbytes}) as defense-in-depth against resource-exhaustion
payloads. Can be overridden per-endpoint via
* {@link VertxHttpConfiguration#setDeserializationFilter(String)} or
globally via the JVM system property
* {@code jdk.serialFilter}.
*/
static final String DEFAULT_DESERIALIZATION_FILTER
- = "!java.net.**;java.**;javax.**;org.apache.camel.**;!*";
+ =
"!java.net.**;java.**;javax.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*";
private static final Logger LOG =
LoggerFactory.getLogger(VertxHttpHelper.class);
diff --git
a/components/camel-vertx/camel-vertx-http/src/test/java/org/apache/camel/component/vertx/http/VertxHttpHelperDeserializationFilterTest.java
b/components/camel-vertx/camel-vertx-http/src/test/java/org/apache/camel/component/vertx/http/VertxHttpHelperDeserializationFilterTest.java
index f6ffeb7245b9..631d091aed14 100644
---
a/components/camel-vertx/camel-vertx-http/src/test/java/org/apache/camel/component/vertx/http/VertxHttpHelperDeserializationFilterTest.java
+++
b/components/camel-vertx/camel-vertx-http/src/test/java/org/apache/camel/component/vertx/http/VertxHttpHelperDeserializationFilterTest.java
@@ -29,9 +29,18 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class VertxHttpHelperDeserializationFilterTest {
+ @Test
+ public void testDefaultFilterContainsGraphShapeLimits() {
+ String filter = VertxHttpHelper.DEFAULT_DESERIALIZATION_FILTER;
+ assertTrue(filter.contains("maxdepth="), "Expected maxdepth in filter:
" + filter);
+ assertTrue(filter.contains("maxrefs="), "Expected maxrefs in filter: "
+ filter);
+ assertTrue(filter.contains("maxbytes="), "Expected maxbytes in filter:
" + filter);
+ }
+
@Test
public void testDeserializeAllowlistedType() throws Exception {
InputStream is = serialize("hello");
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
index d5902c60d10d..71ad189092ad 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
@@ -1490,3 +1490,48 @@ itself (property-source decryption at runtime) is
unaffected.
The components camel-paho is deprecated. There were no new release since 2020
of the Java client, last non-regulatory commit was in 2022.
+=== Tightened default ObjectInputFilter across deserialization sites -
potential breaking change
+
+The in-code default `ObjectInputFilter` shipped by the following components
now includes JEP-290 graph-shape limits
+(`maxdepth=20`, `maxrefs=10000`, `maxbytes=10485760`) in addition to the
existing class allowlist:
+
+* `camel-infinispan` - `DefaultExchangeHolderUtils` (remote aggregation
repository deserialization)
+* `camel-mina` - `MinaConverter` (on-the-wire object stream)
+* `camel-netty` - `NettyConverter` (on-the-wire object stream)
+* `camel-netty-http` - `NettyHttpHelper` (HTTP body deserialization when
`transferException=true`)
+* `camel-vertx-http` - `VertxHttpHelper` (HTTP body deserialization)
+* `camel-leveldb` - `LevelDBAggregationRepository.deserializationFilter`
default value
+* `camel-cassandraql` - `CassandraAggregationRepository.deserializationFilter`
default value
+* `camel-consul` - `ConsulRegistry.deserializationFilter` default value
+* `camel-sql` - `JdbcAggregationRepository.deserializationFilter` default value
+
+The new defaults are:
+
+*
`!java.net.**;java.**;javax.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*`
+ (camel-infinispan, camel-mina, camel-netty, camel-netty-http,
camel-vertx-http)
+*
`!java.net.**;java.**;org.apache.camel.**;maxdepth=20;maxrefs=10000;maxbytes=10485760;!*`
+ (camel-leveldb, camel-cassandraql, camel-consul, camel-sql)
+
+These limits provide defense-in-depth so that operators who have not set
`-Djdk.serialFilter` still get
+sensible graph-shape limits out of the box. The class allowlist is unchanged.
+
+Operators retain the existing override paths:
+
+* The JVM-wide `-Djdk.serialFilter` system property takes precedence over the
Camel default in every site
+ that ships one. Set it to a value that includes the structural clauses you
want (or leave them out to
+ disable structural checks).
+* On the configurable repositories and endpoint configurations
(`LevelDBAggregationRepository`,
+ `JdbcAggregationRepository`, `CassandraAggregationRepository`,
`ConsulRegistry`, the netty-http /
+ vertx-http endpoint configuration), the existing `deserializationFilter`
option accepts a fully custom
+ filter string and can be used to relax or further tighten the defaults per
endpoint.
+
+Routes that legitimately deserialize very deep, very wide, or very large
object graphs may need to either
+raise the structural limits via the `deserializationFilter` option or via
`-Djdk.serialFilter`, or migrate
+off Java serialization entirely.
+
+Note that `camel-jms` and `camel-sjms` apply their filter as a
post-deserialization class check (after
+the JMS provider has already decoded the payload). Graph-shape limits are
therefore not meaningful in
+those sites and have not been added; DoS hardening on the JMS path must be
configured at the JMS provider
+level (for example Artemis `deserializationAllowList`, ActiveMQ Classic
`SERIALIZABLE_PACKAGES`) or via
+`-Djdk.serialFilter`.
+