diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java index b8fb42e0e9..095363cf8d 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java @@ -17,8 +17,8 @@ public class DataUtils { */ public static E handleDataWithSecret(E data) { E dataForLog = data; - if(data instanceof String && StringUtils.contains((String)data, "&secret=")){ - dataForLog = (E) RegExUtils.replaceAll((String)data,"&secret=\\w+&","&secret=******&"); + if (data instanceof String && StringUtils.contains((String) data, "secret=")) { + dataForLog = (E) RegExUtils.replaceAll((String) data, "(^|[?&])secret=[^&]*", "$1secret=******"); } return dataForLog; } diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/DataUtilsTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/DataUtilsTest.java index f5732d9a0b..66a336c268 100644 --- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/DataUtilsTest.java +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/DataUtilsTest.java @@ -19,4 +19,32 @@ public void testHandleDataWithSecret() { final String s = DataUtils.handleDataWithSecret(data); assertTrue(s.contains("&secret=******&")); } + + @Test + public void testHandleDataWithSecretAtEnd() { + // Secret is the last parameter in the query string, so there is no trailing & + String data = "appid=wx123&secret=abc123"; + final String s = DataUtils.handleDataWithSecret(data); + assertFalse(s.contains("abc123"), "Secret at the end of the string should be masked"); + assertTrue(s.contains("secret=******"), "Secret should be replaced with asterisks"); + } + + @Test + public void testHandleDataWithSecretAsFirstParam() { + // Secret is the first/only parameter, so there is no leading & + String data = "secret=abc123&appid=wx123"; + final String s = DataUtils.handleDataWithSecret(data); + assertFalse(s.contains("abc123"), "Secret as the first parameter should be masked"); + assertTrue(s.contains("secret=******"), "Secret should be replaced with asterisks"); + } + + @Test + public void testHandleDataWithSecretEncodedValue() { + // The secret value contains URL-encoded and non-word characters; the whole value must be masked + String data = "appid=wx123&secret=abc%2Fdef-.+ghi&grant_type=client_credential"; + final String s = DataUtils.handleDataWithSecret(data); + assertFalse(s.contains("def"), "The full secret value must be masked, including after non-word characters"); + assertFalse(s.contains("%2F"), "Encoded characters in the secret must be masked too"); + assertTrue(s.contains("&secret=******&"), "Secret should be replaced with asterisks"); + } }