CVE-2026-40473
Description
The camel-mina component's MinaConverter.toObjectInput(IoBuffer) type converter wraps an IoBuffer in a java.io.ObjectInputStream without applying any ObjectInputFilter or class-loading restrictions. When a Camel route uses camel-mina as a TCP or UDP consumer and requests conversion to ObjectInput (for example via getBody(ObjectInput.class) or @Body ObjectInput), an attacker sending a crafted serialized Java object over the network to the MINA consumer port can trigger arbitrary code execution in the context of the application during readObject().
This issue affects Apache Camel: from 3.0.0 before 4.14.6, from 4.15.0 before 4.18.2, from 4.19.0 before 4.20.0.
Users are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.6. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.2.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.camel:camel-minaMaven | >= 3.0.0, < 4.14.6 | 4.14.6 |
org.apache.camel:camel-minaMaven | >= 4.15.0, < 4.18.2 | 4.18.2 |
org.apache.camel:camel-minaMaven | >= 4.19.0, < 4.20.0 | 4.20.0 |
Affected products
2Patches
38e7f6335d2b4CAMEL-23319: Add deserialization filtering to camel-mina converter (#22585)
3 files changed · +90 −1
components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaConverter.java+20 −1 modified@@ -19,18 +19,28 @@ import java.io.IOException; import java.io.InputStream; import java.io.ObjectInput; +import java.io.ObjectInputFilter; import java.io.ObjectInputStream; import org.apache.camel.Converter; import org.apache.camel.Exchange; import org.apache.camel.StreamCache; import org.apache.mina.core.buffer.IoBuffer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A set of converter methods for working with MINA types */ @Converter(generateLoader = true) public final class MinaConverter { + private static final Logger LOG = LoggerFactory.getLogger(MinaConverter.class); + + /** + * 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}. + */ + static final String DEFAULT_DESERIALIZATION_FILTER = "java.**;javax.**;org.apache.camel.**;!*"; private MinaConverter() { //Utility Class @@ -59,7 +69,16 @@ public static InputStream toInputStream(IoBuffer buffer) { @Converter public static ObjectInput toObjectInput(IoBuffer buffer) throws IOException { InputStream is = toInputStream(buffer); - return new ObjectInputStream(is); + ObjectInputStream ois = new ObjectInputStream(is); + ObjectInputFilter jvmFilter = ObjectInputFilter.Config.getSerialFilter(); + if (jvmFilter != null) { + ois.setObjectInputFilter(jvmFilter); + } else { + LOG.debug("No JVM-wide deserialization filter set, applying default Camel filter: {}", + DEFAULT_DESERIALIZATION_FILTER); + ois.setObjectInputFilter(ObjectInputFilter.Config.createFilter(DEFAULT_DESERIALIZATION_FILTER)); + } + return ois; } @Converter
components/camel-mina/src/test/java/com/example/external/NotAllowedSerializable.java+37 −0 added@@ -0,0 +1,37 @@ +/* + * 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 com.example.external; + +import java.io.Serializable; + +/** + * Serializable type living outside the {@code java.**}, {@code javax.**} and {@code org.apache.camel.**} packages, used + * to verify that the default deserialization allowlist rejects unknown classes. + */ +public final class NotAllowedSerializable implements Serializable { + private static final long serialVersionUID = 1L; + + private final String value; + + public NotAllowedSerializable(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +}
components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaConverterTest.java+33 −0 modified@@ -16,18 +16,25 @@ */ package org.apache.camel.component.mina; +import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInput; +import java.io.ObjectOutputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; +import com.example.external.NotAllowedSerializable; import org.apache.camel.Exchange; import org.apache.camel.impl.DefaultCamelContext; import org.apache.camel.support.DefaultExchange; import org.apache.mina.core.buffer.IoBuffer; 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.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; public class MinaConverterTest { @@ -97,4 +104,30 @@ public void testToByteBuffer() { assertEquals(in[i], out[i]); } } + + @Test + public void testToObjectInputAcceptsAllowlistedTypes() throws Exception { + IoBuffer bb = serialize("hello"); + try (ObjectInput in = MinaConverter.toObjectInput(bb)) { + Object value = in.readObject(); + assertInstanceOf(String.class, value); + assertEquals("hello", value); + } + } + + @Test + public void testToObjectInputRejectsUnlistedTypes() throws Exception { + IoBuffer bb = serialize(new NotAllowedSerializable("blocked")); + try (ObjectInput in = MinaConverter.toObjectInput(bb)) { + assertThrows(InvalidClassException.class, in::readObject); + } + } + + private static IoBuffer serialize(Object value) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { + oos.writeObject(value); + } + return IoBuffer.wrap(baos.toByteArray()); + } }
b605816d11c2CAMEL-23319: Add deserialization filtering to camel-mina converter (#22584)
3 files changed · +90 −1
components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaConverter.java+20 −1 modified@@ -19,18 +19,28 @@ import java.io.IOException; import java.io.InputStream; import java.io.ObjectInput; +import java.io.ObjectInputFilter; import java.io.ObjectInputStream; import org.apache.camel.Converter; import org.apache.camel.Exchange; import org.apache.camel.StreamCache; import org.apache.mina.core.buffer.IoBuffer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A set of converter methods for working with MINA types */ @Converter(generateLoader = true) public final class MinaConverter { + private static final Logger LOG = LoggerFactory.getLogger(MinaConverter.class); + + /** + * 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}. + */ + static final String DEFAULT_DESERIALIZATION_FILTER = "java.**;javax.**;org.apache.camel.**;!*"; private MinaConverter() { //Utility Class @@ -59,7 +69,16 @@ public static InputStream toInputStream(IoBuffer buffer) { @Converter public static ObjectInput toObjectInput(IoBuffer buffer) throws IOException { InputStream is = toInputStream(buffer); - return new ObjectInputStream(is); + ObjectInputStream ois = new ObjectInputStream(is); + ObjectInputFilter jvmFilter = ObjectInputFilter.Config.getSerialFilter(); + if (jvmFilter != null) { + ois.setObjectInputFilter(jvmFilter); + } else { + LOG.debug("No JVM-wide deserialization filter set, applying default Camel filter: {}", + DEFAULT_DESERIALIZATION_FILTER); + ois.setObjectInputFilter(ObjectInputFilter.Config.createFilter(DEFAULT_DESERIALIZATION_FILTER)); + } + return ois; } @Converter
components/camel-mina/src/test/java/com/example/external/NotAllowedSerializable.java+37 −0 added@@ -0,0 +1,37 @@ +/* + * 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 com.example.external; + +import java.io.Serializable; + +/** + * Serializable type living outside the {@code java.**}, {@code javax.**} and {@code org.apache.camel.**} packages, used + * to verify that the default deserialization allowlist rejects unknown classes. + */ +public final class NotAllowedSerializable implements Serializable { + private static final long serialVersionUID = 1L; + + private final String value; + + public NotAllowedSerializable(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +}
components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaConverterTest.java+33 −0 modified@@ -16,18 +16,25 @@ */ package org.apache.camel.component.mina; +import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInput; +import java.io.ObjectOutputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; +import com.example.external.NotAllowedSerializable; import org.apache.camel.Exchange; import org.apache.camel.impl.DefaultCamelContext; import org.apache.camel.support.DefaultExchange; import org.apache.mina.core.buffer.IoBuffer; 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.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; public class MinaConverterTest { @@ -97,4 +104,30 @@ public void testToByteBuffer() { assertEquals(in[i], out[i]); } } + + @Test + public void testToObjectInputAcceptsAllowlistedTypes() throws Exception { + IoBuffer bb = serialize("hello"); + try (ObjectInput in = MinaConverter.toObjectInput(bb)) { + Object value = in.readObject(); + assertInstanceOf(String.class, value); + assertEquals("hello", value); + } + } + + @Test + public void testToObjectInputRejectsUnlistedTypes() throws Exception { + IoBuffer bb = serialize(new NotAllowedSerializable("blocked")); + try (ObjectInput in = MinaConverter.toObjectInput(bb)) { + assertThrows(InvalidClassException.class, in::readObject); + } + } + + private static IoBuffer serialize(Object value) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { + oos.writeObject(value); + } + return IoBuffer.wrap(baos.toByteArray()); + } }
c35b0a3720f8CAMEL-23319: Add deserialization filtering to camel-mina converter (#22583)
3 files changed · +90 −1
components/camel-mina/src/main/java/org/apache/camel/component/mina/MinaConverter.java+20 −1 modified@@ -19,18 +19,28 @@ import java.io.IOException; import java.io.InputStream; import java.io.ObjectInput; +import java.io.ObjectInputFilter; import java.io.ObjectInputStream; import org.apache.camel.Converter; import org.apache.camel.Exchange; import org.apache.camel.StreamCache; import org.apache.mina.core.buffer.IoBuffer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A set of converter methods for working with MINA types */ @Converter(generateLoader = true) public final class MinaConverter { + private static final Logger LOG = LoggerFactory.getLogger(MinaConverter.class); + + /** + * 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}. + */ + static final String DEFAULT_DESERIALIZATION_FILTER = "java.**;javax.**;org.apache.camel.**;!*"; private MinaConverter() { //Utility Class @@ -59,7 +69,16 @@ public static InputStream toInputStream(IoBuffer buffer) { @Converter public static ObjectInput toObjectInput(IoBuffer buffer) throws IOException { InputStream is = toInputStream(buffer); - return new ObjectInputStream(is); + ObjectInputStream ois = new ObjectInputStream(is); + ObjectInputFilter jvmFilter = ObjectInputFilter.Config.getSerialFilter(); + if (jvmFilter != null) { + ois.setObjectInputFilter(jvmFilter); + } else { + LOG.debug("No JVM-wide deserialization filter set, applying default Camel filter: {}", + DEFAULT_DESERIALIZATION_FILTER); + ois.setObjectInputFilter(ObjectInputFilter.Config.createFilter(DEFAULT_DESERIALIZATION_FILTER)); + } + return ois; } @Converter
components/camel-mina/src/test/java/com/example/external/NotAllowedSerializable.java+37 −0 added@@ -0,0 +1,37 @@ +/* + * 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 com.example.external; + +import java.io.Serializable; + +/** + * Serializable type living outside the {@code java.**}, {@code javax.**} and {@code org.apache.camel.**} packages, used + * to verify that the default deserialization allowlist rejects unknown classes. + */ +public final class NotAllowedSerializable implements Serializable { + private static final long serialVersionUID = 1L; + + private final String value; + + public NotAllowedSerializable(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +}
components/camel-mina/src/test/java/org/apache/camel/component/mina/MinaConverterTest.java+33 −0 modified@@ -16,18 +16,25 @@ */ package org.apache.camel.component.mina; +import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInput; +import java.io.ObjectOutputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; +import com.example.external.NotAllowedSerializable; import org.apache.camel.Exchange; import org.apache.camel.impl.DefaultCamelContext; import org.apache.camel.support.DefaultExchange; import org.apache.mina.core.buffer.IoBuffer; 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.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; public class MinaConverterTest { @@ -97,4 +104,30 @@ public void testToByteBuffer() { assertEquals(in[i], out[i]); } } + + @Test + public void testToObjectInputAcceptsAllowlistedTypes() throws Exception { + IoBuffer bb = serialize("hello"); + try (ObjectInput in = MinaConverter.toObjectInput(bb)) { + Object value = in.readObject(); + assertInstanceOf(String.class, value); + assertEquals("hello", value); + } + } + + @Test + public void testToObjectInputRejectsUnlistedTypes() throws Exception { + IoBuffer bb = serialize(new NotAllowedSerializable("blocked")); + try (ObjectInput in = MinaConverter.toObjectInput(bb)) { + assertThrows(InvalidClassException.class, in::readObject); + } + } + + private static IoBuffer serialize(Object value) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { + oos.writeObject(value); + } + return IoBuffer.wrap(baos.toByteArray()); + } }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- www.openwall.com/lists/oss-security/2026/04/26/8nvdMailing ListThird Party AdvisoryWEB
- camel.apache.org/security/CVE-2026-40473.htmlnvdVendor AdvisoryWEB
- github.com/advisories/GHSA-vpr3-2659-rw55ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-40473ghsaADVISORY
- github.com/apache/camel/commit/8e7f6335d2b4b096df26f8221723405ceaee275aghsaWEB
- github.com/apache/camel/commit/b605816d11c253d22989abc290c198be83e3f817ghsaWEB
- github.com/apache/camel/commit/c35b0a3720f8c80025b06112d5d9c2932426d7f0ghsaWEB
- github.com/apache/camel/pull/22583ghsaWEB
- github.com/apache/camel/pull/22584ghsaWEB
- github.com/apache/camel/pull/22585ghsaWEB
- issues.apache.org/jira/browse/CAMEL-23319ghsaWEB
News mentions
0No linked articles in our index yet.