This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch camel-4.0.x in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.0.x by this push: new d12927b4884 CAMEL-20306 - Camel-CassandraQL: Add ObjectInputFilter String pattern parameter in CassandraAggregationRepository to be used in unmarshall operations (#12760) d12927b4884 is described below commit d12927b4884d60392cce59fe16bb0260cc4bcdca Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Thu Jan 11 12:33:43 2024 +0100 CAMEL-20306 - Camel-CassandraQL: Add ObjectInputFilter String pattern parameter in CassandraAggregationRepository to be used in unmarshall operations (#12760) * CAMEL-20306 - Camel-CassandraQL: Add ObjectInputFilter String pattern parameter in CassandraAggregationRepository to be used in unmarshall operations Signed-off-by: Andrea Cosentino <anco...@gmail.com> * CAMEL-20306 - Camel-CassandraQL: Add ObjectInputFilter String pattern parameter in CassandraAggregationRepository to be used in unmarshall operations - Docs Signed-off-by: Andrea Cosentino <anco...@gmail.com> --------- Signed-off-by: Andrea Cosentino <anco...@gmail.com> --- .../src/main/docs/cql-component.adoc | 4 ++ .../cassandra/CassandraAggregationRepository.java | 19 +++++++- .../aggregate/cassandra/CassandraCamelCodec.java | 15 +++--- .../cassandra/CassandraCamelCodecTest.java | 56 ++++++++++++++++++++++ .../test/java/org/malicious/example/Employee.java | 46 ++++++++++++++++++ 5 files changed, 131 insertions(+), 9 deletions(-) diff --git a/components/camel-cassandraql/src/main/docs/cql-component.adoc b/components/camel-cassandraql/src/main/docs/cql-component.adoc index a6b0ad65c73..c4390099c77 100644 --- a/components/camel-cassandraql/src/main/docs/cql-component.adoc +++ b/components/camel-cassandraql/src/main/docs/cql-component.adoc @@ -187,6 +187,10 @@ Alternatively, the `CassandraAggregationRepository` does not have a `LOCAL_QUORUM`… |======================================================================= +While deserializing it's important to notice that the the unmarshallExchange method will allow only all java packages and subpackages +and org.apache.camel packages and subpackages. The remaining classes will be blacklisted. So you'll need to change the filter in case of need. +This could be accomplished by changing the deserializationFilter field on the repository. + == Examples To insert something on a table you can use the following code: 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 00277bbfccd..b64653a96f1 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 @@ -121,6 +121,14 @@ public class CassandraAggregationRepository extends ServiceSupport implements Re private boolean allowSerializedHeaders; + /** + * 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. + */ + private String deserializationFilter = "java.**;org.apache.camel.**;!*"; + public CassandraAggregationRepository() { } @@ -211,7 +219,8 @@ public class CassandraAggregationRepository extends ServiceSupport implements Re Exchange exchange = null; if (row != null) { try { - exchange = exchangeCodec.unmarshallExchange(camelContext, row.getByteBuffer(exchangeColumn)); + exchange = exchangeCodec.unmarshallExchange(camelContext, row.getByteBuffer(exchangeColumn), + deserializationFilter); } catch (IOException iOException) { throw new CassandraAggregationException("Failed to read exchange", exchange, iOException); } catch (ClassNotFoundException classNotFoundException) { @@ -468,4 +477,12 @@ public class CassandraAggregationRepository extends ServiceSupport implements Re public void setAllowSerializedHeaders(boolean allowSerializedHeaders) { this.allowSerializedHeaders = allowSerializedHeaders; } + + public String getDeserializationFilter() { + return deserializationFilter; + } + + public void setDeserializationFilter(String deserializationFilter) { + this.deserializationFilter = deserializationFilter; + } } diff --git a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraCamelCodec.java b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraCamelCodec.java index a4332a718a6..1cd72bc038b 100644 --- a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraCamelCodec.java +++ b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraCamelCodec.java @@ -16,11 +16,7 @@ */ package org.apache.camel.processor.aggregate.cassandra; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.io.*; import java.nio.ByteBuffer; import org.apache.camel.CamelContext; @@ -62,9 +58,10 @@ public class CassandraCamelCodec { return ByteBuffer.wrap(serialize(pe)); } - public Exchange unmarshallExchange(CamelContext camelContext, ByteBuffer buffer) + public Exchange unmarshallExchange(CamelContext camelContext, ByteBuffer buffer, String deserializationFilter) throws IOException, ClassNotFoundException { - DefaultExchangeHolder pe = (DefaultExchangeHolder) deserialize(camelContext, new ByteBufferInputStream(buffer)); + DefaultExchangeHolder pe + = (DefaultExchangeHolder) deserialize(camelContext, new ByteBufferInputStream(buffer), deserializationFilter); Exchange answer = new DefaultExchange(camelContext); DefaultExchangeHolder.unmarshal(answer, pe); // restore the from endpoint @@ -86,9 +83,11 @@ public class CassandraCamelCodec { return bytesOut.toByteArray(); } - private Object deserialize(CamelContext camelContext, InputStream bytes) throws IOException, ClassNotFoundException { + private Object deserialize(CamelContext camelContext, InputStream bytes, String deserializationFilter) + throws IOException, ClassNotFoundException { ClassLoader classLoader = camelContext.getApplicationContextClassLoader(); ObjectInputStream objectIn = new ClassLoadingAwareObjectInputStream(classLoader, bytes); + objectIn.setObjectInputFilter(ObjectInputFilter.Config.createFilter(deserializationFilter)); Object object = objectIn.readObject(); objectIn.close(); return object; diff --git a/components/camel-cassandraql/src/test/java/org/apache/camel/processor/aggregate/cassandra/CassandraCamelCodecTest.java b/components/camel-cassandraql/src/test/java/org/apache/camel/processor/aggregate/cassandra/CassandraCamelCodecTest.java new file mode 100644 index 00000000000..f7f08a7f664 --- /dev/null +++ b/components/camel-cassandraql/src/test/java/org/apache/camel/processor/aggregate/cassandra/CassandraCamelCodecTest.java @@ -0,0 +1,56 @@ +/* + * 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 java.io.*; +import java.nio.ByteBuffer; + +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 CassandraCamelCodecTest extends CamelTestSupport { + + CassandraCamelCodec codec; + + @Override + protected void startCamelContext() throws Exception { + super.startCamelContext(); + codec = new CassandraCamelCodec(); + } + + @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, ByteBuffer.wrap(is.readAllBytes()), "java.**;org.apache.camel.**;!*"); + }); + + Assertions.assertEquals("filter status: REJECTED", thrown.getMessage()); + } +} diff --git a/components/camel-cassandraql/src/test/java/org/malicious/example/Employee.java b/components/camel-cassandraql/src/test/java/org/malicious/example/Employee.java new file mode 100644 index 00000000000..3850218d128 --- /dev/null +++ b/components/camel-cassandraql/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; + } +}