Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
badc83d3
Commit
badc83d3
authored
Feb 01, 2020
by
cbono
Committed by
Madhura Bhave
Feb 07, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add 'uris', 'address' and 'addresses' to keys to sanitize.
See gh-19999
parent
45fd6033
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
117 additions
and
21 deletions
+117
-21
Sanitizer.java
.../org/springframework/boot/actuate/endpoint/Sanitizer.java
+28
-7
ConfigurationPropertiesReportEndpointTests.java
...roperties/ConfigurationPropertiesReportEndpointTests.java
+21
-2
SanitizerTests.java
...springframework/boot/actuate/endpoint/SanitizerTests.java
+58
-11
EnvironmentEndpointTests.java
...gframework/boot/actuate/env/EnvironmentEndpointTests.java
+10
-1
No files found.
spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/Sanitizer.java
View file @
badc83d3
...
@@ -16,8 +16,10 @@
...
@@ -16,8 +16,10 @@
package
org
.
springframework
.
boot
.
actuate
.
endpoint
;
package
org
.
springframework
.
boot
.
actuate
.
endpoint
;
import
java.util.Arrays
;
import
java.util.regex.Matcher
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
java.util.regex.Pattern
;
import
java.util.stream.Collectors
;
import
org.springframework.util.Assert
;
import
org.springframework.util.Assert
;
import
org.springframework.util.StringUtils
;
import
org.springframework.util.StringUtils
;
...
@@ -32,18 +34,23 @@ import org.springframework.util.StringUtils;
...
@@ -32,18 +34,23 @@ import org.springframework.util.StringUtils;
* @author Nicolas Lejeune
* @author Nicolas Lejeune
* @author Stephane Nicoll
* @author Stephane Nicoll
* @author HaiTao Zhang
* @author HaiTao Zhang
* @author Chris Bono
* @since 2.0.0
* @since 2.0.0
*/
*/
public
class
Sanitizer
{
public
class
Sanitizer
{
private
static
final
String
[]
REGEX_PARTS
=
{
"*"
,
"$"
,
"^"
,
"+"
};
private
static
final
String
[]
REGEX_PARTS
=
{
"*"
,
"$"
,
"^"
,
"+"
};
private
static
final
String
[]
DEFAULT_KEYS_TO_SANITIZE
=
{
"password"
,
"secret"
,
"key"
,
"token"
,
".*credentials.*"
,
"vcap_services"
,
"sun.java.command"
,
"uri"
,
"uris"
,
"address"
,
"addresses"
};
private
static
final
String
[]
URI_USERINFO_KEYS
=
{
"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
;
private
Pattern
[]
keysToSanitize
;
public
Sanitizer
()
{
public
Sanitizer
()
{
this
(
"password"
,
"secret"
,
"key"
,
"token"
,
".*credentials.*"
,
"vcap_services"
,
"sun.java.command"
,
"uri"
);
this
(
DEFAULT_KEYS_TO_SANITIZE
);
}
}
public
Sanitizer
(
String
...
keysToSanitize
)
{
public
Sanitizer
(
String
...
keysToSanitize
)
{
...
@@ -91,8 +98,8 @@ public class Sanitizer {
...
@@ -91,8 +98,8 @@ public class Sanitizer {
}
}
for
(
Pattern
pattern
:
this
.
keysToSanitize
)
{
for
(
Pattern
pattern
:
this
.
keysToSanitize
)
{
if
(
pattern
.
matcher
(
key
).
matches
())
{
if
(
pattern
.
matcher
(
key
).
matches
())
{
if
(
pattern
.
matcher
(
"uri"
).
matches
(
))
{
if
(
keyIsUriWithUserInfo
(
pattern
))
{
return
sanitizeUri
(
value
);
return
sanitizeUri
s
(
value
.
toString
()
);
}
}
return
"******"
;
return
"******"
;
}
}
...
@@ -100,14 +107,28 @@ public class Sanitizer {
...
@@ -100,14 +107,28 @@ public class Sanitizer {
return
value
;
return
value
;
}
}
private
Object
sanitizeUri
(
Object
value
)
{
private
boolean
keyIsUriWithUserInfo
(
Pattern
pattern
)
{
String
uriString
=
value
.
toString
();
for
(
String
uriKey
:
URI_USERINFO_KEYS
)
{
if
(
pattern
.
matcher
(
uriKey
).
matches
())
{
return
true
;
}
}
return
false
;
}
private
Object
sanitizeUris
(
String
uriString
)
{
// Treat each uri value as possibly containing multiple uris (comma separated)
return
Arrays
.
stream
(
uriString
.
split
(
","
))
.
map
(
this
::
sanitizeUri
)
.
collect
(
Collectors
.
joining
(
","
));
}
private
String
sanitizeUri
(
String
uriString
)
{
Matcher
matcher
=
URI_USERINFO_PATTERN
.
matcher
(
uriString
);
Matcher
matcher
=
URI_USERINFO_PATTERN
.
matcher
(
uriString
);
String
password
=
matcher
.
matches
()
?
matcher
.
group
(
1
)
:
null
;
String
password
=
matcher
.
matches
()
?
matcher
.
group
(
1
)
:
null
;
if
(
password
!=
null
)
{
if
(
password
!=
null
)
{
return
StringUtils
.
replace
(
uriString
,
":"
+
password
+
"@"
,
":******@"
);
return
StringUtils
.
replace
(
uriString
,
":"
+
password
+
"@"
,
":******@"
);
}
}
return
value
;
return
uriString
;
}
}
}
}
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointTests.java
View file @
badc83d3
...
@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.context.properties;
...
@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.context.properties;
import
java.net.URI
;
import
java.net.URI
;
import
java.time.Duration
;
import
java.time.Duration
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
...
@@ -51,6 +52,7 @@ import static org.assertj.core.api.Assertions.entry;
...
@@ -51,6 +52,7 @@ import static org.assertj.core.api.Assertions.entry;
* @author Andy Wilkinson
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Stephane Nicoll
* @author HaiTao Zhang
* @author HaiTao Zhang
* @author Chris Bono
*/
*/
class
ConfigurationPropertiesReportEndpointTests
{
class
ConfigurationPropertiesReportEndpointTests
{
...
@@ -170,19 +172,26 @@ class ConfigurationPropertiesReportEndpointTests {
...
@@ -170,19 +172,26 @@ class ConfigurationPropertiesReportEndpointTests {
}
}
@Test
@Test
void
sanitize
d
UriWithSensitiveInfo
()
{
void
sanitizeUriWithSensitiveInfo
()
{
this
.
contextRunner
.
withUserConfiguration
(
SensiblePropertiesConfiguration
.
class
)
this
.
contextRunner
.
withUserConfiguration
(
SensiblePropertiesConfiguration
.
class
)
.
run
(
assertProperties
(
"sensible"
,
(
properties
)
->
assertThat
(
properties
.
get
(
"sensitiveUri"
))
.
run
(
assertProperties
(
"sensible"
,
(
properties
)
->
assertThat
(
properties
.
get
(
"sensitiveUri"
))
.
isEqualTo
(
"http://user:******@localhost:8080"
)));
.
isEqualTo
(
"http://user:******@localhost:8080"
)));
}
}
@Test
@Test
void
sanitize
d
UriWithNoPassword
()
{
void
sanitizeUriWithNoPassword
()
{
this
.
contextRunner
.
withUserConfiguration
(
SensiblePropertiesConfiguration
.
class
)
this
.
contextRunner
.
withUserConfiguration
(
SensiblePropertiesConfiguration
.
class
)
.
run
(
assertProperties
(
"sensible"
,
(
properties
)
->
assertThat
(
properties
.
get
(
"noPasswordUri"
))
.
run
(
assertProperties
(
"sensible"
,
(
properties
)
->
assertThat
(
properties
.
get
(
"noPasswordUri"
))
.
isEqualTo
(
"http://user:******@localhost:8080"
)));
.
isEqualTo
(
"http://user:******@localhost:8080"
)));
}
}
@Test
void
sanitizeAddressesFieldContainingMultipleRawSensitiveUris
()
{
this
.
contextRunner
.
withUserConfiguration
(
SensiblePropertiesConfiguration
.
class
)
.
run
(
assertProperties
(
"sensible"
,
(
properties
)
->
assertThat
(
properties
.
get
(
"rawSensitiveAddresses"
))
.
isEqualTo
(
"http://user:******@localhost:8080,http://user2:******@localhost:8082"
)));
}
@Test
@Test
void
sanitizeLists
()
{
void
sanitizeLists
()
{
this
.
contextRunner
.
withUserConfiguration
(
SensiblePropertiesConfiguration
.
class
)
this
.
contextRunner
.
withUserConfiguration
(
SensiblePropertiesConfiguration
.
class
)
...
@@ -574,6 +583,8 @@ class ConfigurationPropertiesReportEndpointTests {
...
@@ -574,6 +583,8 @@ class ConfigurationPropertiesReportEndpointTests {
private
URI
noPasswordUri
=
URI
.
create
(
"http://user:@localhost:8080"
);
private
URI
noPasswordUri
=
URI
.
create
(
"http://user:@localhost:8080"
);
private
String
rawSensitiveAddresses
=
"http://user:password@localhost:8080,http://user2:password2@localhost:8082"
;
private
List
<
ListItem
>
listItems
=
new
ArrayList
<>();
private
List
<
ListItem
>
listItems
=
new
ArrayList
<>();
private
List
<
List
<
ListItem
>>
listOfListItems
=
new
ArrayList
<>();
private
List
<
List
<
ListItem
>>
listOfListItems
=
new
ArrayList
<>();
...
@@ -599,6 +610,14 @@ class ConfigurationPropertiesReportEndpointTests {
...
@@ -599,6 +610,14 @@ class ConfigurationPropertiesReportEndpointTests {
return
this
.
noPasswordUri
;
return
this
.
noPasswordUri
;
}
}
public
String
getRawSensitiveAddresses
()
{
return
this
.
rawSensitiveAddresses
;
}
public
void
setRawSensitiveAddresses
(
final
String
rawSensitiveAddresses
)
{
this
.
rawSensitiveAddresses
=
rawSensitiveAddresses
;
}
public
List
<
ListItem
>
getListItems
()
{
public
List
<
ListItem
>
getListItems
()
{
return
this
.
listItems
;
return
this
.
listItems
;
}
}
...
...
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/SanitizerTests.java
View file @
badc83d3
...
@@ -17,6 +17,10 @@
...
@@ -17,6 +17,10 @@
package
org
.
springframework
.
boot
.
actuate
.
endpoint
;
package
org
.
springframework
.
boot
.
actuate
.
endpoint
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.params.ParameterizedTest
;
import
org.junit.jupiter.params.provider.MethodSource
;
import
java.util.stream.Stream
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
...
@@ -25,11 +29,12 @@ import static org.assertj.core.api.Assertions.assertThat;
...
@@ -25,11 +29,12 @@ import static org.assertj.core.api.Assertions.assertThat;
*
*
* @author Phillip Webb
* @author Phillip Webb
* @author Stephane Nicoll
* @author Stephane Nicoll
* @author Chris Bono
*/
*/
class
SanitizerTests
{
class
SanitizerTests
{
@Test
@Test
void
defaults
()
{
void
default
NonUriKey
s
()
{
Sanitizer
sanitizer
=
new
Sanitizer
();
Sanitizer
sanitizer
=
new
Sanitizer
();
assertThat
(
sanitizer
.
sanitize
(
"password"
,
"secret"
)).
isEqualTo
(
"******"
);
assertThat
(
sanitizer
.
sanitize
(
"password"
,
"secret"
)).
isEqualTo
(
"******"
);
assertThat
(
sanitizer
.
sanitize
(
"my-password"
,
"secret"
)).
isEqualTo
(
"******"
);
assertThat
(
sanitizer
.
sanitize
(
"my-password"
,
"secret"
)).
isEqualTo
(
"******"
);
...
@@ -40,21 +45,64 @@ class SanitizerTests {
...
@@ -40,21 +45,64 @@ class SanitizerTests {
assertThat
(
sanitizer
.
sanitize
(
"sometoken"
,
"secret"
)).
isEqualTo
(
"******"
);
assertThat
(
sanitizer
.
sanitize
(
"sometoken"
,
"secret"
)).
isEqualTo
(
"******"
);
assertThat
(
sanitizer
.
sanitize
(
"find"
,
"secret"
)).
isEqualTo
(
"secret"
);
assertThat
(
sanitizer
.
sanitize
(
"find"
,
"secret"
)).
isEqualTo
(
"secret"
);
assertThat
(
sanitizer
.
sanitize
(
"sun.java.command"
,
"--spring.redis.password=pa55w0rd"
)).
isEqualTo
(
"******"
);
assertThat
(
sanitizer
.
sanitize
(
"sun.java.command"
,
"--spring.redis.password=pa55w0rd"
)).
isEqualTo
(
"******"
);
assertThat
(
sanitizer
.
sanitize
(
"my.uri"
,
"http://user:password@localhost:8080"
))
.
isEqualTo
(
"http://user:******@localhost:8080"
);
}
}
@Test
@ParameterizedTest
(
name
=
"key = {0}"
)
void
uriWithNoPasswordShouldNotBeSanitized
()
{
@MethodSource
(
"matchingUriUserInfoKeys"
)
void
uriWithSingleEntryWithPasswordShouldBeSanitized
(
String
key
)
{
Sanitizer
sanitizer
=
new
Sanitizer
();
Sanitizer
sanitizer
=
new
Sanitizer
();
assertThat
(
sanitizer
.
sanitize
(
"my.uri"
,
"http://localhost:8080"
)).
isEqualTo
(
"http://
localhost:8080"
);
assertThat
(
sanitizer
.
sanitize
(
key
,
"http://user:password@localhost:8080"
)).
isEqualTo
(
"http://user:******@
localhost:8080"
);
}
}
@Test
@ParameterizedTest
(
name
=
"key = {0}"
)
void
uriWithPasswordMatchingOtherPartsOfString
()
{
@MethodSource
(
"matchingUriUserInfoKeys"
)
void
uriWithSingleEntryWithNoPasswordShouldNotBeSanitized
(
String
key
)
{
Sanitizer
sanitizer
=
new
Sanitizer
();
assertThat
(
sanitizer
.
sanitize
(
key
,
"http://localhost:8080"
)).
isEqualTo
(
"http://localhost:8080"
);
assertThat
(
sanitizer
.
sanitize
(
key
,
"http://user@localhost:8080"
)).
isEqualTo
(
"http://user@localhost:8080"
);
}
@ParameterizedTest
(
name
=
"key = {0}"
)
@MethodSource
(
"matchingUriUserInfoKeys"
)
void
uriWithSingleEntryWithPasswordMatchingOtherPartsOfStringShouldBeSanitized
(
String
key
)
{
Sanitizer
sanitizer
=
new
Sanitizer
();
Sanitizer
sanitizer
=
new
Sanitizer
();
assertThat
(
sanitizer
.
sanitize
(
"my.uri"
,
"http://user://@localhost:8080"
))
assertThat
(
sanitizer
.
sanitize
(
key
,
"http://user://@localhost:8080"
)).
isEqualTo
(
"http://user:******@localhost:8080"
);
.
isEqualTo
(
"http://user:******@localhost:8080"
);
}
@ParameterizedTest
(
name
=
"key = {0}"
)
@MethodSource
(
"matchingUriUserInfoKeys"
)
void
uriWithMultipleEntriesEachWithPasswordShouldHaveAllSanitized
(
String
key
)
{
Sanitizer
sanitizer
=
new
Sanitizer
();
assertThat
(
sanitizer
.
sanitize
(
key
,
"http://user1:password1@localhost:8080,http://user2:password2@localhost:8082"
))
.
isEqualTo
(
"http://user1:******@localhost:8080,http://user2:******@localhost:8082"
);
}
@ParameterizedTest
(
name
=
"key = {0}"
)
@MethodSource
(
"matchingUriUserInfoKeys"
)
void
uriWithMultipleEntriesNoneWithPasswordShouldHaveNoneSanitized
(
String
key
)
{
Sanitizer
sanitizer
=
new
Sanitizer
();
assertThat
(
sanitizer
.
sanitize
(
key
,
"http://user@localhost:8080,http://localhost:8082"
))
.
isEqualTo
(
"http://user@localhost:8080,http://localhost:8082"
);
}
@ParameterizedTest
(
name
=
"key = {0}"
)
@MethodSource
(
"matchingUriUserInfoKeys"
)
void
uriWithMultipleEntriesSomeWithPasswordShouldHaveThoseSanitized
(
String
key
)
{
Sanitizer
sanitizer
=
new
Sanitizer
();
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"
);
}
@ParameterizedTest
(
name
=
"key = {0}"
)
@MethodSource
(
"matchingUriUserInfoKeys"
)
void
uriWithMultipleEntriesWithPasswordMatchingOtherPartsOfStringShouldBeSanitized
(
String
key
)
{
Sanitizer
sanitizer
=
new
Sanitizer
();
assertThat
(
sanitizer
.
sanitize
(
key
,
"http://user1://@localhost:8080,http://user2://@localhost:8082"
))
.
isEqualTo
(
"http://user1:******@localhost:8080,http://user2:******@localhost:8082"
);
}
static
private
Stream
<
String
>
matchingUriUserInfoKeys
()
{
return
Stream
.
of
(
"uri"
,
"my.uri"
,
"myuri"
,
"uris"
,
"my.uris"
,
"myuris"
,
"address"
,
"my.address"
,
"myaddress"
,
"addresses"
,
"my.addresses"
,
"myaddresses"
);
}
}
@Test
@Test
...
@@ -63,5 +111,4 @@ class SanitizerTests {
...
@@ -63,5 +111,4 @@ class SanitizerTests {
assertThat
(
sanitizer
.
sanitize
(
"verylOCkish"
,
"secret"
)).
isEqualTo
(
"******"
);
assertThat
(
sanitizer
.
sanitize
(
"verylOCkish"
,
"secret"
)).
isEqualTo
(
"******"
);
assertThat
(
sanitizer
.
sanitize
(
"veryokish"
,
"secret"
)).
isEqualTo
(
"secret"
);
assertThat
(
sanitizer
.
sanitize
(
"veryokish"
,
"secret"
)).
isEqualTo
(
"secret"
);
}
}
}
}
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/env/EnvironmentEndpointTests.java
View file @
badc83d3
...
@@ -50,6 +50,7 @@ import static org.assertj.core.api.Assertions.assertThat;
...
@@ -50,6 +50,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Madhura Bhave
* @author Madhura Bhave
* @author Andy Wilkinson
* @author Andy Wilkinson
* @author HaiTao Zhang
* @author HaiTao Zhang
* @author Chris Bono
*/
*/
class
EnvironmentEndpointTests
{
class
EnvironmentEndpointTests
{
...
@@ -246,13 +247,21 @@ class EnvironmentEndpointTests {
...
@@ -246,13 +247,21 @@ class EnvironmentEndpointTests {
}
}
@Test
@Test
void
uriPropert
r
yWithSensitiveInfo
()
{
void
uriPropertyWithSensitiveInfo
()
{
ConfigurableEnvironment
environment
=
new
StandardEnvironment
();
ConfigurableEnvironment
environment
=
new
StandardEnvironment
();
TestPropertyValues
.
of
(
"sensitive.uri=http://user:password@localhost:8080"
).
applyTo
(
environment
);
TestPropertyValues
.
of
(
"sensitive.uri=http://user:password@localhost:8080"
).
applyTo
(
environment
);
EnvironmentEntryDescriptor
descriptor
=
new
EnvironmentEndpoint
(
environment
).
environmentEntry
(
"sensitive.uri"
);
EnvironmentEntryDescriptor
descriptor
=
new
EnvironmentEndpoint
(
environment
).
environmentEntry
(
"sensitive.uri"
);
assertThat
(
descriptor
.
getProperty
().
getValue
()).
isEqualTo
(
"http://user:******@localhost:8080"
);
assertThat
(
descriptor
.
getProperty
().
getValue
()).
isEqualTo
(
"http://user:******@localhost:8080"
);
}
}
@Test
void
addressesPropertyWithMultipleEntriesEachWithSensitiveInfo
()
{
ConfigurableEnvironment
environment
=
new
StandardEnvironment
();
TestPropertyValues
.
of
(
"sensitive.addresses=http://user:password@localhost:8080,http://user2:password2@localhost:8082"
).
applyTo
(
environment
);
EnvironmentEntryDescriptor
descriptor
=
new
EnvironmentEndpoint
(
environment
).
environmentEntry
(
"sensitive.addresses"
);
assertThat
(
descriptor
.
getProperty
().
getValue
()).
isEqualTo
(
"http://user:******@localhost:8080,http://user2:******@localhost:8082"
);
}
private
static
ConfigurableEnvironment
emptyEnvironment
()
{
private
static
ConfigurableEnvironment
emptyEnvironment
()
{
StandardEnvironment
environment
=
new
StandardEnvironment
();
StandardEnvironment
environment
=
new
StandardEnvironment
();
environment
.
getPropertySources
().
remove
(
StandardEnvironment
.
SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME
);
environment
.
getPropertySources
().
remove
(
StandardEnvironment
.
SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment