Skip to content

Commit 80f0314

Browse files
committed
WIP: Actuator Endpoints Sanitization report section
1 parent adfe7bf commit 80f0314

File tree

3 files changed

+151
-0
lines changed

3 files changed

+151
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2021 - 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.sbm.boot.upgrade_27_30.report.helper;
17+
import org.springframework.sbm.boot.common.conditions.IsSpringBootProject;
18+
import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportSection;
19+
import org.springframework.sbm.build.api.BuildFile;
20+
import org.springframework.sbm.build.api.Module;
21+
import org.springframework.sbm.engine.context.ProjectContext;
22+
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.stream.Collectors;
26+
27+
/**
28+
* @author Fabian Krüger
29+
*/
30+
public class ActuatorEndpointsSanitizationHelper extends SpringBootUpgradeReportSection.AbstractHelper<List<BuildFile>> {
31+
32+
private static final String ACTUATOR_GROUP_ID = "org.springframework.boot";
33+
private static final String ACTUATOR_ARTIFACT_ID = "spring-boot-actuator";
34+
private List<BuildFile> buildFilesWithActuatorOnClasspath;
35+
36+
@Override
37+
public boolean evaluate(ProjectContext context) {
38+
IsSpringBootProject isSpringBootProjectCondition = new IsSpringBootProject();
39+
isSpringBootProjectCondition.setVersionPattern("3\\.0\\..*");
40+
boolean isSpringBoot3Application = isSpringBootProjectCondition.evaluate(context);
41+
if(! isSpringBoot3Application) {
42+
return false;
43+
}
44+
buildFilesWithActuatorOnClasspath = getActuatorDependency(context);
45+
return ! buildFilesWithActuatorOnClasspath.isEmpty();
46+
}
47+
48+
private List<BuildFile> getActuatorDependency(ProjectContext context) {
49+
return context.getApplicationModules().stream()
50+
.map(Module::getBuildFile)
51+
.filter(b -> b.getEffectiveDependencies().stream().anyMatch(d -> d.getGroupId().equals(ACTUATOR_GROUP_ID) && d.getArtifactId().equals(ACTUATOR_ARTIFACT_ID)))
52+
.collect(Collectors.toList());
53+
}
54+
55+
@Override
56+
public Map<String, List<BuildFile>> getData() {
57+
return Map.of("matchingBuildFiles", buildFilesWithActuatorOnClasspath);
58+
}
59+
}

components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/report/sbu30-report.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,34 @@
132132
- "Fabian Krüger[@fabapp2]"
133133

134134

135+
- title: Actuator Endpoints Sanitization
136+
helper: org.springframework.sbm.boot.upgrade_27_30.report.helper.ActuatorEndpointsSanitizationHelper
137+
change: |-
138+
Since, the `/env` and `/configprops` endpoints can contains sensitive values, all values are always masked by default.
139+
This used to be case only for keys considered to be sensitive.
140+
141+
Instead, this release opts for a more secure default.
142+
The keys-based approach has been removed in favor of a role based approach, similar to the health endpoint details.
143+
Whether unsanitized values are shown or not can be configured using a property which can have the following values:
144+
145+
- `NEVER` - All values are sanitized.
146+
- `ALWAYS` - All values are present in the output (sanitizing functions will apply).
147+
- `WHEN_AUTHORIZED` - Values are present in the output only if a user is authorized (sanitizing functions will apply).
148+
149+
For JMX, users are always considered to be authorized. For HTTP, users are considered to be authorized if they are authenticated and have the specified roles.
150+
151+
Sanitization for the QuartzEndpoint is also configurable in the same way.
152+
affected:
153+
The scan found a dependency to actuator on the classpath. The Actuator endpoint sanitization changed in Spring Boot 3.0.0.
154+
Because Spring Boot Migrator can't tell if the now sanitized properties are required in plain-text, the default in 2.7 will be reset. This means the application does not benefit from the new and more secure configuration in Spring Boot 3.0.0.
155+
We strongly recommend you adjust this configuration to your needs.
156+
remediation: |-
157+
consult the documentation {Link to relevant section(s) in M5 and current reference}
158+
configure Actuator endpoint sanitization to your needs by adjusting management.endpoint.configprops.show-values, management.endpoint.env.show-values and management.endpoint.quartz.show-values.
159+
githubIssue: 445
160+
contributors:
161+
- "Fabian Krüger[@fabapp2]"
162+
135163
- title: Changes to Data Properties
136164
helper: org.springframework.sbm.boot.upgrade_27_30.report.helper.ChangesToDataPropertiesHelper
137165
change: |-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package org.springframework.sbm.boot.upgrade_27_30.report.helper;
2+
3+
import org.assertj.core.api.Assertions;
4+
import org.junit.jupiter.api.Nested;
5+
import org.junit.jupiter.api.Test;
6+
import org.springframework.sbm.build.util.PomBuilder;
7+
import org.springframework.sbm.engine.context.ProjectContext;
8+
import org.springframework.sbm.project.resource.TestProjectContext;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
import static org.junit.jupiter.api.Assertions.*;
12+
13+
/**
14+
* @author Fabian Krüger
15+
*/
16+
class ActuatorEndpointsSanitizationHelperTest {
17+
18+
@Test
19+
void withSingleModuleApplication() {
20+
ProjectContext context = TestProjectContext
21+
.buildProjectContext()
22+
.withSpringBootParentOf("3.0.0")
23+
.withBuildFileHavingDependencies("org.springframework.boot:spring-boot-actuator")
24+
.build();
25+
26+
ActuatorEndpointsSanitizationHelper sut = new ActuatorEndpointsSanitizationHelper();
27+
assertThat(sut.evaluate(context)).isTrue();
28+
assertThat(sut.getData()).hasSize(1);
29+
assertThat(sut.getData().get("matchingBuildFile")).containsExactly(context.getApplicationModules().getRootModule().getBuildFile());
30+
}
31+
32+
@Test
33+
void withMultiModuleApplication() {
34+
String parentPom = PomBuilder
35+
.buildParentPom("org.springframework.boot:spring-boot-starter-parent:3.0.0", "com.example:parent:1.0")
36+
.withModules("moduleA", "moduleB", "moduleC")
37+
.build();
38+
String moduleA = PomBuilder
39+
.buildPom("com.example:parent:1.0", "moduleA")
40+
.compileScopeDependencies("com.example:moduleC")
41+
.build();
42+
String moduleB = PomBuilder
43+
.buildPom("com.example:parent:1.0", "moduleB")
44+
.compileScopeDependencies("com.example:moduleC")
45+
.build();
46+
String moduleC = PomBuilder
47+
.buildPom("com.example:parent:1.0", "moduleC")
48+
.compileScopeDependencies("org.springframework.boot:spring-boot-actuator")
49+
.build();
50+
51+
ProjectContext context = TestProjectContext
52+
.buildProjectContext()
53+
.withMavenRootBuildFileSource(parentPom)
54+
.withMavenBuildFileSource("moduleA", moduleA)
55+
.withMavenBuildFileSource("moduleB", moduleB)
56+
.withMavenBuildFileSource("moduleC", moduleC)
57+
.build();
58+
59+
ActuatorEndpointsSanitizationHelper sut = new ActuatorEndpointsSanitizationHelper();
60+
assertThat(sut.evaluate(context)).isTrue();
61+
assertThat(sut.getData()).hasSize(3);
62+
}
63+
64+
}

0 commit comments

Comments
 (0)