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 <healc...@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