You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@inlong.apache.org by do...@apache.org on 2022/09/14 06:28:19 UTC

[inlong] branch master updated: [INLONG-5881][Manager] Fix the vulnerability to security attacks for the MySQL JDBC URL (#5884)

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 41981d937 [INLONG-5881][Manager] Fix the vulnerability to security attacks for the MySQL JDBC URL (#5884)
41981d937 is described below

commit 41981d937f49db17ae9ccb71b0021a4dfc33cffd
Author: healchow <he...@gmail.com>
AuthorDate: Wed Sep 14 14:28:13 2022 +0800

    [INLONG-5881][Manager] Fix the vulnerability to security attacks for the MySQL JDBC URL (#5884)
---
 inlong-manager/manager-pojo/pom.xml                | 12 ++++++
 .../manager/pojo/sink/mysql/MySQLSinkDTO.java      | 46 +++++++++++++++++++--
 .../manager/pojo/sink/mysql/MySQLSinkDTOTest.java  | 47 ++++++++++++++++++++++
 .../manager-pojo/src/test/resources/log4j2.xml     | 46 +++++++++++++++++++++
 4 files changed, 147 insertions(+), 4 deletions(-)

diff --git a/inlong-manager/manager-pojo/pom.xml b/inlong-manager/manager-pojo/pom.xml
index 6d8b8e28b..3608519ad 100644
--- a/inlong-manager/manager-pojo/pom.xml
+++ b/inlong-manager/manager-pojo/pom.xml
@@ -69,6 +69,18 @@
             <groupId>io.swagger</groupId>
             <artifactId>swagger-annotations</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
diff --git a/inlong-manager/manager-pojo/src/main/java/org/apache/inlong/manager/pojo/sink/mysql/MySQLSinkDTO.java b/inlong-manager/manager-pojo/src/main/java/org/apache/inlong/manager/pojo/sink/mysql/MySQLSinkDTO.java
index 730aa8587..070456809 100644
--- a/inlong-manager/manager-pojo/src/main/java/org/apache/inlong/manager/pojo/sink/mysql/MySQLSinkDTO.java
+++ b/inlong-manager/manager-pojo/src/main/java/org/apache/inlong/manager/pojo/sink/mysql/MySQLSinkDTO.java
@@ -19,12 +19,14 @@ package org.apache.inlong.manager.pojo.sink.mysql;
 
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.inlong.manager.common.enums.ErrorCodeEnum;
 import org.apache.inlong.manager.common.exceptions.BusinessException;
 import org.slf4j.Logger;
@@ -43,8 +45,14 @@ import java.util.Map;
 @AllArgsConstructor
 public class MySQLSinkDTO {
 
+    @VisibleForTesting
+    protected static final char SYMBOL = '&';
+    /**
+     * The sensitive param may lead the attack.
+     */
+    @VisibleForTesting
+    protected static final String SENSITIVE_PARAM = "autoDeserialize=true";
     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
     private static final Logger LOGGER = LoggerFactory.getLogger(MySQLSinkDTO.class);
 
     @ApiModelProperty("MySQL JDBC URL, such as jdbc:mysql://host:port/database")
@@ -70,10 +78,12 @@ public class MySQLSinkDTO {
      *
      * @param request MySQLSinkRequest
      * @return {@link MySQLSinkDTO}
+     * @apiNote The config here will be saved to the database, so filter sensitive params before saving.
      */
     public static MySQLSinkDTO getFromRequest(MySQLSinkRequest request) {
+        String url = filterSensitive(request.getJdbcUrl());
         return MySQLSinkDTO.builder()
-                .jdbcUrl(request.getJdbcUrl())
+                .jdbcUrl(url)
                 .username(request.getUsername())
                 .password(request.getPassword())
                 .primaryKey(request.getPrimaryKey())
@@ -118,10 +128,10 @@ public class MySQLSinkDTO {
     /**
      * Get DbName from jdbcUrl
      *
-     * @param jdbcUrl  MySQL JDBC url, such as jdbc:mysql://host:port/database
+     * @param jdbcUrl MySQL JDBC url, such as jdbc:mysql://host:port/database
      * @return database name
      */
-    public static String getDbNameFromUrl(String jdbcUrl) {
+    private static String getDbNameFromUrl(String jdbcUrl) {
         String database = null;
 
         if (Strings.isNullOrEmpty(jdbcUrl)) {
@@ -162,4 +172,32 @@ public class MySQLSinkDTO {
         }
         return database;
     }
+
+    /**
+     * Filter the sensitive params for the given URL.
+     *
+     * @param url str may have some sensitive params
+     * @return str without sensitive param
+     */
+    @VisibleForTesting
+    protected static String filterSensitive(String url) {
+        if (StringUtils.isBlank(url) || !url.contains(SENSITIVE_PARAM)) {
+            LOGGER.info("string was empty or not contains sensitive for [{}]", url);
+            return url;
+        }
+
+        String originUrl = url;
+        int index = url.indexOf(SENSITIVE_PARAM);
+        String tmp = SENSITIVE_PARAM;
+        if (index == 0) {
+            tmp = tmp + SYMBOL;
+        } else if (url.charAt(index - 1) == SYMBOL) {
+            tmp = SYMBOL + tmp;
+        }
+
+        url = url.replace(tmp, "");
+        LOGGER.debug("the origin url [{}] was filter to: [{}]", originUrl, url);
+        return url;
+    }
+
 }
diff --git a/inlong-manager/manager-pojo/src/test/java/org/apache/inlong/manager/pojo/sink/mysql/MySQLSinkDTOTest.java b/inlong-manager/manager-pojo/src/test/java/org/apache/inlong/manager/pojo/sink/mysql/MySQLSinkDTOTest.java
new file mode 100644
index 000000000..fabd6842d
--- /dev/null
+++ b/inlong-manager/manager-pojo/src/test/java/org/apache/inlong/manager/pojo/sink/mysql/MySQLSinkDTOTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.manager.pojo.sink.mysql;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.inlong.manager.pojo.sink.mysql.MySQLSinkDTO.SENSITIVE_PARAM;
+import static org.apache.inlong.manager.pojo.sink.mysql.MySQLSinkDTO.SYMBOL;
+
+/**
+ * Test for {@link MySQLSinkDTO}
+ */
+public class MySQLSinkDTOTest {
+
+    @Test
+    public void testFilterOther() {
+        // the sensitive params at the first
+        String originUrl = MySQLSinkDTO.filterSensitive(SENSITIVE_PARAM + SYMBOL + "autoReconnect=true");
+        Assertions.assertEquals("autoReconnect=true", originUrl);
+
+        // the sensitive params at the end
+        originUrl = MySQLSinkDTO.filterSensitive("autoReconnect=true" + SYMBOL + SENSITIVE_PARAM);
+        Assertions.assertEquals("autoReconnect=true", originUrl);
+
+        // the sensitive params in the middle
+        originUrl = MySQLSinkDTO.filterSensitive(
+                "useSSL=false" + SYMBOL + SENSITIVE_PARAM + SYMBOL + "autoReconnect=true");
+        Assertions.assertEquals("useSSL=false" + SYMBOL + "autoReconnect=true", originUrl);
+    }
+
+}
diff --git a/inlong-manager/manager-pojo/src/test/resources/log4j2.xml b/inlong-manager/manager-pojo/src/test/resources/log4j2.xml
new file mode 100644
index 000000000..ba02ec4d7
--- /dev/null
+++ b/inlong-manager/manager-pojo/src/test/resources/log4j2.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<configuration status="WARN" monitorInterval="30">
+    <Properties>
+        <property name="basePath">logs</property>
+        <property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} -%5p [%5.30t] %-30.30C{1.}:%L - %m%n</property>
+        <property name="output_log_level">DEBUG</property>
+        <property name="all_fileName">${basePath}/manager-pojo-ut.log</property>
+        <property name="console_print_level">DEBUG</property>
+    </Properties>
+
+    <appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <ThresholdFilter level="${console_print_level}" onMatch="ACCEPT" onMismatch="DENY"/>
+            <PatternLayout pattern="${log_pattern}"/>
+            <follow>true</follow>
+        </Console>
+        <File name="AllFile" fileName="${all_fileName}">
+            <PatternLayout pattern="${log_pattern}"/>
+        </File>
+    </appenders>
+
+    <loggers>
+        <root level="${output_log_level}">
+            <appender-ref ref="Console"/>
+            <appender-ref ref="AllFile"/>
+        </root>
+    </loggers>
+</configuration>
\ No newline at end of file