Disable web endpoints by default
Since the handler interceptors have been removed, web endpoints are all disabled by default to prevent accidental exposure of sensitive information. Closes gh-7958
This commit is contained in:
parent
e08ddbf838
commit
bacbe0459b
|
|
@ -103,6 +103,10 @@ public class EndpointEnablementProvider {
|
|||
if (globalTypeOutcome != null) {
|
||||
return globalTypeOutcome;
|
||||
}
|
||||
else if (!endpointType.isEnabledByDefault()) {
|
||||
return new EndpointEnablement(false, createDefaultEnablementMessage("all", false,
|
||||
endpointType));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Check if there is a global tech required
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ public class ConditionalOnEnabledEndpointTests {
|
|||
@Test
|
||||
public void enabledOnlyWebByDefault() {
|
||||
this.contextRunner.withUserConfiguration(OnlyWebConfig.class)
|
||||
.withPropertyValues("endpoints.all.web.enabled=true")
|
||||
.run((context) -> assertThat(context).hasBean("onlyweb"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,40 +55,12 @@ public class WebMvcEndpointInfrastructureAutoConfigurationTests {
|
|||
ServletEndpointAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void webEndpointsAreExposed() {
|
||||
this.contextRunner.run((context) -> {
|
||||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/autoconfig"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/beans")).isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/configprops"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/env")).isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/health"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/info")).isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/mappings"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/metrics"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.POST, "/application/shutdown"))
|
||||
.isFalse();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/threaddump"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/trace")).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void webEndpointsCanBeDisabled() {
|
||||
WebApplicationContextRunner contextRunner = this.contextRunner
|
||||
.withPropertyValues("endpoints.all.web.enabled=false");
|
||||
contextRunner.run((context) -> {
|
||||
public void webEndpointsAreDisabledByDefault() {
|
||||
this.contextRunner.run(context -> {
|
||||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/autoconfig"))
|
||||
.isFalse();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/beans"))
|
||||
.isFalse();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/beans")).isFalse();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/configprops"))
|
||||
.isFalse();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/env")).isFalse();
|
||||
|
|
@ -103,8 +75,36 @@ public class WebMvcEndpointInfrastructureAutoConfigurationTests {
|
|||
.isFalse();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/threaddump"))
|
||||
.isFalse();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/trace"))
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/trace")).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void webEndpointsCanBeEnabled() {
|
||||
WebApplicationContextRunner contextRunner = this.contextRunner
|
||||
.withPropertyValues("endpoints.all.web.enabled=true");
|
||||
contextRunner.run(context -> {
|
||||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/autoconfig"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/beans"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/configprops"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/env")).isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/health"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/info")).isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/mappings"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/metrics"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.POST, "/application/shutdown"))
|
||||
.isFalse();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/threaddump"))
|
||||
.isTrue();
|
||||
assertThat(isExposed(mockMvc, HttpMethod.GET, "/application/trace"))
|
||||
.isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -185,8 +185,8 @@ public class EndpointEnablementProviderTests {
|
|||
|
||||
@Test
|
||||
public void specificEnabledByDefault() {
|
||||
validate(determineEnablement("foo", true, EndpointType.WEB), true,
|
||||
"endpoint 'foo' (web) is enabled by default");
|
||||
validate(determineEnablement("foo", true, EndpointType.JMX), true,
|
||||
"endpoint 'foo' (jmx) is enabled by default");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -208,15 +208,15 @@ public class EndpointEnablementProviderTests {
|
|||
@Test
|
||||
public void specificNotDisabledViaUnrelatedTechProperty() {
|
||||
validate(
|
||||
determineEnablement("foo", true, EndpointType.WEB,
|
||||
"endpoints.foo.jmx.enabled=false"),
|
||||
true, "endpoint 'foo' (web) is enabled by default");
|
||||
determineEnablement("foo", true, EndpointType.JMX,
|
||||
"endpoints.foo.web.enabled=false"),
|
||||
true, "endpoint 'foo' (jmx) is enabled by default");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specificDisabledViaGeneralProperty() {
|
||||
validate(
|
||||
determineEnablement("foo", true, EndpointType.WEB,
|
||||
determineEnablement("foo", true, EndpointType.JMX,
|
||||
"endpoints.all.enabled=false"),
|
||||
false, "found property endpoints.all.enabled");
|
||||
}
|
||||
|
|
@ -256,8 +256,8 @@ public class EndpointEnablementProviderTests {
|
|||
@Test
|
||||
public void specificEnabledOverrideHasNoEffectWithUnrelatedTechProperty() {
|
||||
validate(
|
||||
determineEnablement("foo", true, EndpointType.WEB,
|
||||
"endpoints.all.enabled=false", "endpoints.all.jmx.enabled=true"),
|
||||
determineEnablement("foo", true, EndpointType.JMX,
|
||||
"endpoints.all.enabled=false", "endpoints.all.web.enabled=true"),
|
||||
false, "found property endpoints.all.enabled");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,9 @@ public class WebEndpointManagementContextConfigurationTests {
|
|||
}
|
||||
|
||||
private void beanIsAutoConfigured(Class<?> beanType, Class<?>... config) {
|
||||
contextRunner().withUserConfiguration(config)
|
||||
contextRunner()
|
||||
.withPropertyValues("endpoints.all.web.enabled:true")
|
||||
.withUserConfiguration(config)
|
||||
.run((context) -> assertThat(context).hasSingleBean(beanType));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ public class MvcEndpointCorsIntegrationTests {
|
|||
EndpointInfrastructureAutoConfiguration.class,
|
||||
EndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class,
|
||||
ServletEndpointAutoConfiguration.class);
|
||||
TestPropertyValues.of("endpoints.all.web.enabled:true")
|
||||
.applyTo(this.context);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
|
|||
* {@link org.springframework.core.env.Environment} are reset at the end of every test.
|
||||
* This means that {@link TestPropertyValues} can be used in a test without affecting the
|
||||
* {@code Environment} of other tests in the same class.
|
||||
* The runner always sets the flag `endpoints.all.web.enabled` to true so that web endpoints
|
||||
* are enabled.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
|
|
@ -190,6 +192,7 @@ public class WebEndpointsRunner extends Suite {
|
|||
private MvcWebEndpointsRunner(Class<?> klass) throws InitializationError {
|
||||
super(klass, "Spring MVC", (classes) -> {
|
||||
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
|
||||
TestPropertyValues.of("endpoints.all.web.enabled:true").applyTo(context);
|
||||
classes.add(MvcTestConfiguration.class);
|
||||
context.register(classes.toArray(new Class<?>[classes.size()]));
|
||||
context.refresh();
|
||||
|
|
@ -221,6 +224,7 @@ public class WebEndpointsRunner extends Suite {
|
|||
private JerseyWebEndpointsRunner(Class<?> klass) throws InitializationError {
|
||||
super(klass, "Jersey", (classes) -> {
|
||||
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
|
||||
TestPropertyValues.of("endpoints.all.web.enabled:true").applyTo(context);
|
||||
classes.add(JerseyAppConfiguration.class);
|
||||
classes.add(JerseyInfrastructureConfiguration.class);
|
||||
context.register(classes.toArray(new Class<?>[classes.size()]));
|
||||
|
|
@ -260,6 +264,7 @@ public class WebEndpointsRunner extends Suite {
|
|||
private ReactiveWebEndpointsRunner(Class<?> klass) throws InitializationError {
|
||||
super(klass, "Reactive", (classes) -> {
|
||||
ReactiveWebServerApplicationContext context = new ReactiveWebServerApplicationContext();
|
||||
TestPropertyValues.of("endpoints.all.web.enabled:true").applyTo(context);
|
||||
classes.add(ReactiveInfrastructureConfiguration.class);
|
||||
context.register(classes.toArray(new Class<?>[classes.size()]));
|
||||
context.refresh();
|
||||
|
|
|
|||
|
|
@ -27,11 +27,20 @@ public enum EndpointType {
|
|||
/**
|
||||
* Expose the endpoint as a JMX MBean.
|
||||
*/
|
||||
JMX,
|
||||
JMX(true),
|
||||
|
||||
/**
|
||||
* Expose the endpoint as a Web endpoint.
|
||||
*/
|
||||
WEB
|
||||
WEB(false);
|
||||
|
||||
private final boolean enabledByDefault;
|
||||
|
||||
EndpointType(boolean enabledByDefault) {
|
||||
this.enabledByDefault = enabledByDefault;
|
||||
}
|
||||
|
||||
public boolean isEnabledByDefault() {
|
||||
return this.enabledByDefault;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue