This is an automated email from the ASF dual-hosted git repository. dockerzhang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/inlong.git
The following commit(s) were added to refs/heads/master by this push: new 0719f95d3 [INLONG-5889][Sort] Fix MySQL Node JDBC Url For RCE Vulnerability (#5896) 0719f95d3 is described below commit 0719f95d3362540d69c6a7924d33e16a34671826 Author: Schnapps <zpen...@connect.ust.hk> AuthorDate: Thu Sep 15 11:27:23 2022 +0800 [INLONG-5889][Sort] Fix MySQL Node JDBC Url For RCE Vulnerability (#5896) --- .../org/apache/inlong/sort/base/Constants.java | 11 +++++ .../apache/inlong/sort/base/util/JdbcUrlUtils.java | 50 ++++++++++++++++++++++ .../inlong/sort/base/metric/TestUrlValidate.java | 46 ++++++++++++++++++++ .../sort/jdbc/table/JdbcDynamicTableFactory.java | 4 +- .../inlong/sort/cdc/mysql/table/JdbcUrlUtils.java | 9 +++- 5 files changed, 118 insertions(+), 2 deletions(-) diff --git a/inlong-sort/sort-connectors/base/src/main/java/org/apache/inlong/sort/base/Constants.java b/inlong-sort/sort-connectors/base/src/main/java/org/apache/inlong/sort/base/Constants.java index 9dd124284..45023d38b 100644 --- a/inlong-sort/sort-connectors/base/src/main/java/org/apache/inlong/sort/base/Constants.java +++ b/inlong-sort/sort-connectors/base/src/main/java/org/apache/inlong/sort/base/Constants.java @@ -94,4 +94,15 @@ public final class Constants { .defaultValue(false) .withDescription("Regard upsert delete as insert kind."); + + /** + * It is used for jdbc url filter for avoiding url attack + * see also in https://su18.org/post/jdbc-connection-url-attack/ + */ + public static final String AUTO_DESERIALIZE = "autoDeserialize"; + + public static final String AUTO_DESERIALIZE_TRUE = "autoDeserialize=true"; + + public static final String AUTO_DESERIALIZE_FALSE = "autoDeserialize=false"; + } diff --git a/inlong-sort/sort-connectors/base/src/main/java/org/apache/inlong/sort/base/util/JdbcUrlUtils.java b/inlong-sort/sort-connectors/base/src/main/java/org/apache/inlong/sort/base/util/JdbcUrlUtils.java new file mode 100644 index 000000000..253f783ca --- /dev/null +++ b/inlong-sort/sort-connectors/base/src/main/java/org/apache/inlong/sort/base/util/JdbcUrlUtils.java @@ -0,0 +1,50 @@ +/* + * 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.inlong.sort.base.util; + +import static org.apache.inlong.sort.base.Constants.AUTO_DESERIALIZE_FALSE; +import static org.apache.inlong.sort.base.Constants.AUTO_DESERIALIZE_TRUE; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * utils for jdbc url + */ +public class JdbcUrlUtils { + + private static final Logger LOG = LoggerFactory.getLogger(JdbcUrlUtils.class); + + /** + * see https://su18.org/post/jdbc-connection-url-attack/ + * @param url + * @return url after filtering out the invalid property + */ + public static String replaceInvalidUrlProperty(String url) { + if (StringUtils.containsIgnoreCase(url, AUTO_DESERIALIZE_TRUE)) { + LOG.warn("url {} contains invalid property {}, replace it to {}", url, + AUTO_DESERIALIZE_TRUE, AUTO_DESERIALIZE_FALSE); + return StringUtils.replaceIgnoreCase(url, AUTO_DESERIALIZE_TRUE, + AUTO_DESERIALIZE_FALSE); + } + return url; + } + +} diff --git a/inlong-sort/sort-connectors/base/src/test/java/org/apache/inlong/sort/base/metric/TestUrlValidate.java b/inlong-sort/sort-connectors/base/src/test/java/org/apache/inlong/sort/base/metric/TestUrlValidate.java new file mode 100644 index 000000000..8e090e5d3 --- /dev/null +++ b/inlong-sort/sort-connectors/base/src/test/java/org/apache/inlong/sort/base/metric/TestUrlValidate.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.apache.inlong.sort.base.metric; + +import org.apache.inlong.sort.base.util.JdbcUrlUtils; +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for validate jdbc url, see https://su18.org/post/jdbc-connection-url-attack/ + */ +public class TestUrlValidate { + + @Test + public void testJdbcUrlValid() { + final String jdbcUrl = "jdbc:mysql://localhost:8066/dbtest?" + + "detectCustomCollations=true&autoDeserialize=true"; + final String expectResult = "jdbc:mysql://localhost:8066/dbtest?" + + "detectCustomCollations=true&autoDeserialize=false"; + Assert.assertEquals(expectResult, JdbcUrlUtils.replaceInvalidUrlProperty(jdbcUrl)); + + final String jdbcUrlWithCase = "jdbc:mysql://localhost:8066/dbtest?" + + "detectCustomCollations=true&autoDeserialize=tRue"; + final String expectResultWithoutCase = "jdbc:mysql://localhost:8066/dbtest?" + + "detectCustomCollations=true&autoDeserialize=false"; + Assert.assertEquals(expectResultWithoutCase, JdbcUrlUtils.replaceInvalidUrlProperty(jdbcUrlWithCase)); + + } + +} diff --git a/inlong-sort/sort-connectors/jdbc/src/main/java/org/apache/inlong/sort/jdbc/table/JdbcDynamicTableFactory.java b/inlong-sort/sort-connectors/jdbc/src/main/java/org/apache/inlong/sort/jdbc/table/JdbcDynamicTableFactory.java index 1efe0a91b..b8c8e2e6c 100644 --- a/inlong-sort/sort-connectors/jdbc/src/main/java/org/apache/inlong/sort/jdbc/table/JdbcDynamicTableFactory.java +++ b/inlong-sort/sort-connectors/jdbc/src/main/java/org/apache/inlong/sort/jdbc/table/JdbcDynamicTableFactory.java @@ -42,6 +42,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Optional; import java.util.Set; +import org.apache.inlong.sort.base.util.JdbcUrlUtils; import static org.apache.flink.util.Preconditions.checkState; import static org.apache.inlong.sort.base.Constants.INLONG_AUDIT; @@ -59,6 +60,7 @@ import static org.apache.inlong.sort.base.Constants.INLONG_METRIC; public class JdbcDynamicTableFactory implements DynamicTableSourceFactory, DynamicTableSinkFactory { public static final String IDENTIFIER = "jdbc-inlong"; + public static final ConfigOption<String> DIALECT_IMPL = ConfigOptions.key("dialect-impl") .stringType() @@ -218,7 +220,7 @@ public class JdbcDynamicTableFactory implements DynamicTableSourceFactory, Dynam } private JdbcOptions getJdbcOptions(ReadableConfig readableConfig) { - final String url = readableConfig.get(URL); + String url = JdbcUrlUtils.replaceInvalidUrlProperty(readableConfig.get(URL)); Optional<String> dialectImplOptional = readableConfig.getOptional(DIALECT_IMPL); Optional<JdbcDialect> jdbcDialect; if (dialectImplOptional.isPresent()) { diff --git a/inlong-sort/sort-connectors/mysql-cdc/src/main/java/org/apache/inlong/sort/cdc/mysql/table/JdbcUrlUtils.java b/inlong-sort/sort-connectors/mysql-cdc/src/main/java/org/apache/inlong/sort/cdc/mysql/table/JdbcUrlUtils.java index d2f25222b..fab1ffb6a 100644 --- a/inlong-sort/sort-connectors/mysql-cdc/src/main/java/org/apache/inlong/sort/cdc/mysql/table/JdbcUrlUtils.java +++ b/inlong-sort/sort-connectors/mysql-cdc/src/main/java/org/apache/inlong/sort/cdc/mysql/table/JdbcUrlUtils.java @@ -20,6 +20,8 @@ package org.apache.inlong.sort.cdc.mysql.table; import java.util.Map; import java.util.Properties; +import org.apache.commons.lang3.StringUtils; +import org.apache.inlong.sort.base.Constants; /** Option utils for JDBC URL properties. */ public class JdbcUrlUtils { @@ -31,7 +33,7 @@ public class JdbcUrlUtils { Properties jdbcProperties = new Properties(); if (hasJdbcProperties(tableOptions)) { tableOptions.keySet().stream() - .filter(key -> key.startsWith(PROPERTIES_PREFIX)) + .filter(key -> key.startsWith(PROPERTIES_PREFIX) && isValid(key)) .forEach( key -> { final String value = tableOptions.get(key); @@ -49,4 +51,9 @@ public class JdbcUrlUtils { private static boolean hasJdbcProperties(Map<String, String> tableOptions) { return tableOptions.keySet().stream().anyMatch(k -> k.startsWith(PROPERTIES_PREFIX)); } + + private static boolean isValid(String key) { + return !StringUtils.containsIgnoreCase(key, Constants.AUTO_DESERIALIZE); + } + }