From a67166a2cd2dfbf193a76049e8714ee8bf74a4d0 Mon Sep 17 00:00:00 2001 From: Andrea Cosentino Date: Tue, 23 Jun 2026 12:00:59 +0200 Subject: [PATCH] CAMEL-23803: block unsafe polymorphic base types by default in camel-jackson-avro and camel-jackson-protobuf (backport to 4.14.x) The camel-jackson-avro and camel-jackson-protobuf data formats now create their default AvroMapper / ProtobufMapper with MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES enabled, mirroring the hardening applied to camel-jackson (CAMEL-23786) and camel-jacksonxml (CAMEL-23787) and to their respective transform/ mappers. This is defense-in-depth against gadget-chain deserialization: when polymorphic / default typing is enabled, Jackson refuses unsafe base types (Object, Serializable, Comparable). Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Andrea Cosentino --- .../jackson/avro/JacksonAvroDataFormat.java | 8 +++- ...vroDataFormatPolymorphicHardeningTest.java | 48 +++++++++++++++++++ .../protobuf/JacksonProtobufDataFormat.java | 8 +++- ...bufDataFormatPolymorphicHardeningTest.java | 48 +++++++++++++++++++ 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 components/camel-jackson-avro/src/test/java/org/apache/camel/component/jackson/avro/JacksonAvroDataFormatPolymorphicHardeningTest.java create mode 100644 components/camel-jackson-protobuf/src/test/java/org/apache/camel/component/jackson/protobuf/JacksonProtobufDataFormatPolymorphicHardeningTest.java diff --git a/components/camel-jackson-avro/src/main/java/org/apache/camel/component/jackson/avro/JacksonAvroDataFormat.java b/components/camel-jackson-avro/src/main/java/org/apache/camel/component/jackson/avro/JacksonAvroDataFormat.java index 54bb52cba3600..4270f1d935a8e 100644 --- a/components/camel-jackson-avro/src/main/java/org/apache/camel/component/jackson/avro/JacksonAvroDataFormat.java +++ b/components/camel-jackson-avro/src/main/java/org/apache/camel/component/jackson/avro/JacksonAvroDataFormat.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.jackson.avro; +import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.avro.AvroMapper; import org.apache.camel.component.jackson.AbstractJacksonDataFormat; @@ -87,7 +88,12 @@ protected String getDefaultContentType() { @Override protected AvroMapper createNewObjectMapper() { - return new AvroMapper(); + // Enable BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES by default as defense-in-depth against gadget-chain + // deserialization when polymorphic typing is enabled, consistent with camel-jackson (CAMEL-23786) + // and the transform/Avro.java mapper. + return AvroMapper.builder() + .enable(MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES) + .build(); } @Override diff --git a/components/camel-jackson-avro/src/test/java/org/apache/camel/component/jackson/avro/JacksonAvroDataFormatPolymorphicHardeningTest.java b/components/camel-jackson-avro/src/test/java/org/apache/camel/component/jackson/avro/JacksonAvroDataFormatPolymorphicHardeningTest.java new file mode 100644 index 0000000000000..97be889c050f1 --- /dev/null +++ b/components/camel-jackson-avro/src/test/java/org/apache/camel/component/jackson/avro/JacksonAvroDataFormatPolymorphicHardeningTest.java @@ -0,0 +1,48 @@ +/* + * 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.jackson.avro; + +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.camel.impl.DefaultCamelContext; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Verifies that the AvroMapper created by {@link JacksonAvroDataFormat} enables + * {@link MapperFeature#BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES} by default — the Jackson mechanism that refuses unsafe + * polymorphic base types (e.g. Object/Serializable) when polymorphic/default typing is enabled, as defense-in-depth + * against gadget-chain deserialization. + */ +public class JacksonAvroDataFormatPolymorphicHardeningTest { + + @Test + void blockUnsafePolymorphicBaseTypesEnabledByDefault() throws Exception { + try (DefaultCamelContext context = new DefaultCamelContext()) { + context.start(); + JacksonAvroDataFormat df = new JacksonAvroDataFormat(); + df.setCamelContext(context); + df.start(); + ObjectMapper mapper = df.getObjectMapper(); + assertNotNull(mapper); + assertTrue(mapper.isEnabled(MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES), + "camel-jackson-avro data format must enable BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES by default"); + } + } +} diff --git a/components/camel-jackson-protobuf/src/main/java/org/apache/camel/component/jackson/protobuf/JacksonProtobufDataFormat.java b/components/camel-jackson-protobuf/src/main/java/org/apache/camel/component/jackson/protobuf/JacksonProtobufDataFormat.java index 554c9082aa88a..34f3cad4dd98f 100644 --- a/components/camel-jackson-protobuf/src/main/java/org/apache/camel/component/jackson/protobuf/JacksonProtobufDataFormat.java +++ b/components/camel-jackson-protobuf/src/main/java/org/apache/camel/component/jackson/protobuf/JacksonProtobufDataFormat.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.jackson.protobuf; +import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.protobuf.ProtobufMapper; import org.apache.camel.component.jackson.AbstractJacksonDataFormat; @@ -88,7 +89,12 @@ protected String getDefaultContentType() { @Override protected ProtobufMapper createNewObjectMapper() { - return new ProtobufMapper(); + // Enable BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES by default as defense-in-depth against gadget-chain + // deserialization when polymorphic typing is enabled, consistent with camel-jackson (CAMEL-23786) + // and the transform/Protobuf.java mapper. + return ProtobufMapper.builder() + .enable(MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES) + .build(); } @Override diff --git a/components/camel-jackson-protobuf/src/test/java/org/apache/camel/component/jackson/protobuf/JacksonProtobufDataFormatPolymorphicHardeningTest.java b/components/camel-jackson-protobuf/src/test/java/org/apache/camel/component/jackson/protobuf/JacksonProtobufDataFormatPolymorphicHardeningTest.java new file mode 100644 index 0000000000000..a16b69ac6edad --- /dev/null +++ b/components/camel-jackson-protobuf/src/test/java/org/apache/camel/component/jackson/protobuf/JacksonProtobufDataFormatPolymorphicHardeningTest.java @@ -0,0 +1,48 @@ +/* + * 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.jackson.protobuf; + +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.camel.impl.DefaultCamelContext; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Verifies that the ProtobufMapper created by {@link JacksonProtobufDataFormat} enables + * {@link MapperFeature#BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES} by default — the Jackson mechanism that refuses unsafe + * polymorphic base types (e.g. Object/Serializable) when polymorphic/default typing is enabled, as defense-in-depth + * against gadget-chain deserialization. + */ +public class JacksonProtobufDataFormatPolymorphicHardeningTest { + + @Test + void blockUnsafePolymorphicBaseTypesEnabledByDefault() throws Exception { + try (DefaultCamelContext context = new DefaultCamelContext()) { + context.start(); + JacksonProtobufDataFormat df = new JacksonProtobufDataFormat(); + df.setCamelContext(context); + df.start(); + ObjectMapper mapper = df.getObjectMapper(); + assertNotNull(mapper); + assertTrue(mapper.isEnabled(MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES), + "camel-jackson-protobuf data format must enable BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES by default"); + } + } +}