Skip to content

Commit 8749fc7

Browse files
author
Dave Syer
committed
Disallow all extensions in actuator endpoints (except .json)
Along with the recent change in Spring to use content-disposition "inline" (which prevents the download), it also makes sense to limit the extensions allowed by the actuator endpoints. Really there *is* no extension for these endpoints, but since all of them explicitly produce JSON we can add .json for browsers as a convenience in case the app would otherwise choose to send XML. Fixes gh-4402
1 parent 1204559 commit 8749fc7

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMapping.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public EndpointHandlerMapping(Collection<? extends MvcEndpoint> endpoints,
8484
// By default the static resource handler mapping is LOWEST_PRECEDENCE - 1
8585
// and the RequestMappingHandlerMapping is 0 (we ideally want to be before both)
8686
setOrder(-100);
87+
setUseSuffixPatternMatch(false);
8788
}
8889

8990
@Override
@@ -121,7 +122,7 @@ private String[] getPatterns(Object handler, RequestMappingInfo mapping) {
121122
String prefix = StringUtils.hasText(this.prefix) ? this.prefix + path : path;
122123
Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns();
123124
if (defaultPatterns.isEmpty()) {
124-
return new String[] { prefix };
125+
return new String[] { prefix, prefix + ".json" };
125126
}
126127
List<String> patterns = new ArrayList<String>(defaultPatterns);
127128
for (int i = 0; i < patterns.size(); i++) {
@@ -142,7 +143,8 @@ private String getPath(Object handler) {
142143

143144
private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping,
144145
String[] patternStrings) {
145-
PatternsRequestCondition patterns = new PatternsRequestCondition(patternStrings);
146+
PatternsRequestCondition patterns = new PatternsRequestCondition(patternStrings,
147+
null, null, useSuffixPatternMatch(), useTrailingSlashMatch(), null);
146148
return new RequestMappingInfo(patterns, mapping.getMethodsCondition(),
147149
mapping.getParamsCondition(), mapping.getHeadersCondition(),
148150
mapping.getConsumesCondition(), mapping.getProducesCondition(),

spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpointIntegrationTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,22 @@ public void jsonResponsesCanBeIndentedWhenSpringDataRestIsAutoConfigured()
9090
assertIndentedJsonResponse(SpringDataRestConfiguration.class);
9191
}
9292

93+
@Test
94+
public void fileExtensionNotFound() throws Exception {
95+
this.context = new AnnotationConfigWebApplicationContext();
96+
this.context.register(DefaultConfiguration.class);
97+
MockMvc mockMvc = createMockMvc();
98+
mockMvc.perform(get("/beans.cmd")).andExpect(status().isNotFound());
99+
}
100+
101+
@Test
102+
public void jsonExtensionProvided() throws Exception {
103+
this.context = new AnnotationConfigWebApplicationContext();
104+
this.context.register(DefaultConfiguration.class);
105+
MockMvc mockMvc = createMockMvc();
106+
mockMvc.perform(get("/beans.json")).andExpect(status().isOk());
107+
}
108+
93109
@Test
94110
public void nonSensitiveEndpointsAreNotSecureByDefault() throws Exception {
95111
this.context = new AnnotationConfigWebApplicationContext();

0 commit comments

Comments
 (0)