From 73993e98ee272ccbd1a0bb160eda5c7557ddc21e Mon Sep 17 00:00:00 2001 From: calvin Date: Thu, 30 Dec 2021 16:09:59 +0800 Subject: [PATCH] [Fix-7713] Handling the sensitive data in the log (#7728) * add a feature to handle sensitive data --- .../api/aspect/AccessLogAspect.java | 31 ++++++++++++++ .../api/aspect/AccessLogAspectTest.java | 42 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspectTest.java diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspect.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspect.java index 14d75c7f74..b20b6d8425 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspect.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspect.java @@ -26,7 +26,10 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Set; import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.IntStream; import javax.servlet.http.HttpServletRequest; @@ -48,6 +51,10 @@ public class AccessLogAspect { private static final String TRACE_ID = "traceId"; + public static final String sensitiveDataRegEx = "(password=[\'\"]+)(\\S+)([\'\"]+)"; + + private static final Pattern sensitiveDataPattern = Pattern.compile(sensitiveDataRegEx, Pattern.CASE_INSENSITIVE); + @Pointcut("@annotation(org.apache.dolphinscheduler.api.aspect.AccessLogAnnotation)") public void logPointCut(){ // Do nothing because of it's a pointcut @@ -78,6 +85,8 @@ public class AccessLogAspect { // handle args String argsString = parseArgs(proceedingJoinPoint, annotation); + // handle sensitive data in the string + argsString = handleSensitiveData(argsString); logger.info("REQUEST TRACE_ID:{}, LOGIN_USER:{}, URI:{}, METHOD:{}, HANDLER:{}, ARGS:{}", traceId, userName, @@ -119,6 +128,28 @@ public class AccessLogAspect { return argsString; } + protected String handleSensitiveData(String originalData) { + Matcher matcher = sensitiveDataPattern.matcher(originalData.toLowerCase()); + IntStream stream = IntStream.builder().build(); + boolean exists = false; + while (matcher.find()) { + if (matcher.groupCount() == 3) { + stream = IntStream.concat(stream, IntStream.range(matcher.end(1),matcher.end(2))); + exists = true; + } + } + + if (exists) { + char[] chars = originalData.toCharArray(); + stream.forEach(idx -> { + chars[idx] = '*'; + }); + return new String(chars); + } + + return originalData; + } + private String parseLoginInfo(HttpServletRequest request) { String userName = "NOT LOGIN"; User loginUser = (User) (request.getAttribute(Constants.SESSION_USER)); diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspectTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspectTest.java new file mode 100644 index 0000000000..e272e4256e --- /dev/null +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/aspect/AccessLogAspectTest.java @@ -0,0 +1,42 @@ +/* + * 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.dolphinscheduler.api.aspect; + +import org.junit.Assert; +import org.junit.jupiter.api.Test; + +/** + * @author Hua Jiang + */ + +public class AccessLogAspectTest { + + private AccessLogAspect accessLogAspect = new AccessLogAspect(); + + @Test + public void testHandleSensitiveData() { + String data = "userPassword='7ad2410b2f4c074479a8937a28a22b8f', email='xxx@qq.com', database='null', userName='root', password='root', other='null'"; + String expected = "userPassword='********************************', email='xxx@qq.com', database='null', userName='root', password='****', other='null'"; + + String actual = accessLogAspect.handleSensitiveData(data); + + Assert.assertEquals(expected, actual); + + } + +}