diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/Sanitizer.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/Sanitizer.java index a0a0d345304..d0c2e735393 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/Sanitizer.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/Sanitizer.java @@ -37,6 +37,7 @@ import org.springframework.util.StringUtils; * @author Stephane Nicoll * @author HaiTao Zhang * @author Chris Bono + * @author David Good * @since 2.0.0 */ public class Sanitizer { @@ -49,7 +50,7 @@ public class Sanitizer { private static final Set URI_USERINFO_KEYS = new LinkedHashSet<>( Arrays.asList("uri", "uris", "address", "addresses")); - private static final Pattern URI_USERINFO_PATTERN = Pattern.compile("[A-Za-z]+://.+:(.*)@.+$"); + private static final Pattern URI_USERINFO_PATTERN = Pattern.compile("\\[?[A-Za-z]+://.+:(.*)@.+$"); private Pattern[] keysToSanitize; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/SanitizerTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/SanitizerTests.java index 9785411463f..0a8f0b22cf8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/SanitizerTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/SanitizerTests.java @@ -30,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Phillip Webb * @author Stephane Nicoll * @author Chris Bono + * @author David Good */ class SanitizerTests { @@ -105,6 +106,22 @@ class SanitizerTests { .isEqualTo("http://user1:******@localhost:8080,http://user2:******@localhost:8082"); } + @ParameterizedTest(name = "key = {0}") + @MethodSource("matchingUriUserInfoKeys") + void uriKeyWithUserProvidedListLiteralShouldBeSanitized(String key) { + Sanitizer sanitizer = new Sanitizer(); + assertThat(sanitizer.sanitize(key, "[amqp://username:password@host/]")) + .isEqualTo("[amqp://username:******@host/]"); + assertThat(sanitizer.sanitize(key, + "[http://user1:password1@localhost:8080,http://user2@localhost:8082,http://localhost:8083]")).isEqualTo( + "[http://user1:******@localhost:8080,http://user2@localhost:8082,http://localhost:8083]"); + assertThat(sanitizer.sanitize(key, + "[http://user1:password1@localhost:8080,http://user2:password2@localhost:8082]")) + .isEqualTo("[http://user1:******@localhost:8080,http://user2:******@localhost:8082]"); + assertThat(sanitizer.sanitize(key, "[http://user1@localhost:8080,http://user2@localhost:8082]")) + .isEqualTo("[http://user1@localhost:8080,http://user2@localhost:8082]"); + } + private static Stream matchingUriUserInfoKeys() { return Stream.of("uri", "my.uri", "myuri", "uris", "my.uris", "myuris", "address", "my.address", "myaddress", "addresses", "my.addresses", "myaddresses"); diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc index 39830d83332..0fc2ed9c983 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc @@ -2232,10 +2232,13 @@ Information returned by the `env` and `configprops` endpoints can be somewhat se The patterns to use can be customized using the `management.endpoint.env.keys-to-sanitize` and `management.endpoint.configprops.keys-to-sanitize` respectively. -Spring Boot uses sensible defaults for such keys: any key ending with the word "password", "secret", "key", "token", "vcap_services", "sun.java.command", "uri", "uris", "address" or "addresses" is sanitized. -Additionally, any key that holds the word `credentials` as part of the key is sanitized (configured as a regular expression, i.e. `+.*credentials.*+`). +Spring Boot uses sensible defaults for such keys: any key ending with the word "password", "secret", "key", "token", "vcap_services", "sun.java.command" is entirely sanitized. +Additionally, any key that holds the word `credentials` as part of the key is sanitized (configured as a regular expression, i.e. `+*credentials.*+`). -If any of the keys to sanitize are URI format (i.e. `://:@:/`), only the password part is sanitized. +Furthermore, Spring Boot only sanitizes the sensitive portion of URIs for keys which end with "uri", "uris", "address", or "addresses". +The sensitive portion of the URI is identified using the format `://:@:/`. +For example, for the property `myclient.uri=http://user1:password1@localhost:8081`, the resulting sanitized value is +`++http://user1:******@localhost:8081++`.