This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch CAMEL-20303-3.22.x in repository https://gitbox.apache.org/repos/asf/camel.git
commit f3c5acbca12d2f517b8302d60a4ca8f9c5aa5560 Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Tue Jan 9 10:58:54 2024 +0100 CAMEL-20303 - Camel-Sql: Add ObjectInputFilter String pattern parameter in JdbcAggregationRepository to be used in unmarshall operations (#12707) Signed-off-by: Andrea Cosentino <anco...@gmail.com> --- .../aggregate/jdbc/JdbcAggregationRepository.java | 17 ++++++- .../processor/aggregate/jdbc/JdbcCamelCodec.java | 20 ++++---- .../aggregate/jdbc/JdbcCamelCodecTest.java | 55 ++++++++++++++++++++++ .../test/java/org/malicious/example/Employee.java | 46 ++++++++++++++++++ 4 files changed, 125 insertions(+), 13 deletions(-) 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 107ca88d1ac..9504b8e7a43 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 @@ -94,6 +94,7 @@ public class JdbcAggregationRepository extends ServiceSupport private String deadLetterUri; private List<String> headersToStoreAsText; private boolean storeBodyAsText; + private String deserializationFilter = "java.**;org.apache.camel.**;!*"; /** * Creates an aggregation repository @@ -357,7 +358,7 @@ public class JdbcAggregationRepository extends ServiceSupport version = (long) versionObj; } - Exchange result = codec.unmarshallExchange(camelContext, marshalledExchange); + Exchange result = codec.unmarshallExchange(camelContext, marshalledExchange, deserializationFilter); result.setProperty(VERSION_PROPERTY, version); return result; @@ -626,6 +627,20 @@ public class JdbcAggregationRepository extends ServiceSupport return getRepositoryName() + "_completed"; } + public String getDeserializationFilter() { + return deserializationFilter; + } + + /** + * 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. + */ + public void setDeserializationFilter(String deserializationFilter) { + this.deserializationFilter = deserializationFilter; + } + @Override protected void doInit() throws Exception { super.doInit(); diff --git a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcCamelCodec.java b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcCamelCodec.java index 7f4b1a12c48..b6395dba43b 100644 --- a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcCamelCodec.java +++ b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcCamelCodec.java @@ -16,13 +16,7 @@ */ package org.apache.camel.processor.aggregate.jdbc; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; +import java.io.*; import org.apache.camel.CamelContext; import org.apache.camel.Endpoint; @@ -74,13 +68,14 @@ public class JdbcCamelCodec { encode(pe, outputStream); } - public Exchange unmarshallExchange(CamelContext camelContext, byte[] buffer) throws IOException, ClassNotFoundException { - return unmarshallExchange(camelContext, new ByteArrayInputStream(buffer)); + public Exchange unmarshallExchange(CamelContext camelContext, byte[] buffer, String deserializationFilter) + throws IOException, ClassNotFoundException { + return unmarshallExchange(camelContext, new ByteArrayInputStream(buffer), deserializationFilter); } - public Exchange unmarshallExchange(CamelContext camelContext, InputStream inputStream) + public Exchange unmarshallExchange(CamelContext camelContext, InputStream inputStream, String deserializationFilter) throws IOException, ClassNotFoundException { - DefaultExchangeHolder pe = decode(camelContext, inputStream); + DefaultExchangeHolder pe = decode(camelContext, inputStream, deserializationFilter); Exchange answer = new DefaultExchange(camelContext); DefaultExchangeHolder.unmarshal(answer, pe); // restore the from endpoint @@ -100,12 +95,13 @@ public class JdbcCamelCodec { } } - private DefaultExchangeHolder decode(CamelContext camelContext, InputStream bytesIn) + private DefaultExchangeHolder decode(CamelContext camelContext, InputStream bytesIn, String deserializationFilter) throws IOException, ClassNotFoundException { ObjectInputStream objectIn = null; Object obj = null; try { objectIn = new ClassLoadingAwareObjectInputStream(camelContext.getApplicationContextClassLoader(), bytesIn); + objectIn.setObjectInputFilter(ObjectInputFilter.Config.createFilter(deserializationFilter)); obj = objectIn.readObject(); } finally { IOHelper.close(objectIn); diff --git a/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcCamelCodecTest.java b/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcCamelCodecTest.java new file mode 100644 index 00000000000..726049f12ad --- /dev/null +++ b/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcCamelCodecTest.java @@ -0,0 +1,55 @@ +/* + * 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 java.io.*; + +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.malicious.example.Employee; + +public class JdbcCamelCodecTest extends CamelTestSupport { + + JdbcCamelCodec codec; + + @Override + protected void startCamelContext() throws Exception { + super.startCamelContext(); + codec = new JdbcCamelCodec(); + } + + @Test + public void shouldFailWithRejected() throws IOException, ClassNotFoundException { + Employee emp = new Employee("Mickey", "Mouse"); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + + oos.writeObject(emp); + + oos.flush(); + oos.close(); + + InputStream is = new ByteArrayInputStream(baos.toByteArray()); + InvalidClassException thrown = Assertions.assertThrows(InvalidClassException.class, () -> { + codec.unmarshallExchange(context, is, "java.**;org.apache.camel.**;!*"); + }); + + Assertions.assertEquals("filter status: REJECTED", thrown.getMessage()); + } +} diff --git a/components/camel-sql/src/test/java/org/malicious/example/Employee.java b/components/camel-sql/src/test/java/org/malicious/example/Employee.java new file mode 100644 index 00000000000..3850218d128 --- /dev/null +++ b/components/camel-sql/src/test/java/org/malicious/example/Employee.java @@ -0,0 +1,46 @@ +/* + * 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.malicious.example; + +import java.io.Serializable; + +public class Employee implements Serializable { + + String name; + String surname; + + public Employee(String name, String surname) { + this.name = name; + this.surname = surname; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } +}