You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2024/01/09 10:25:22 UTC

(camel) branch camel-3.x updated: CAMEL-20303 - Camel-Sql: Add ObjectInputFilter String pattern parameter in JdbcAggregationRepository to be used in unmarshall operations (#12708)

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch camel-3.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-3.x by this push:
     new c8538803432 CAMEL-20303 - Camel-Sql: Add ObjectInputFilter String pattern parameter in JdbcAggregationRepository to be used in unmarshall operations (#12708)
c8538803432 is described below

commit c8538803432ebcc7c4707bab2532d2787ea27770
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Tue Jan 9 11:25:16 2024 +0100

    CAMEL-20303 - Camel-Sql: Add ObjectInputFilter String pattern parameter in JdbcAggregationRepository to be used in unmarshall operations (#12708)
    
    Signed-off-by: Andrea Cosentino <an...@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;
+    }
+}