From fceceb480fd5b7432b6606fc5fecc2a32dd03a60 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 11 Jan 2021 20:54:27 +0000 Subject: [PATCH] Validate Resource type in ResourceHttpRequestHandler --- .../resource/ResourceHttpRequestHandler.java | 7 +++++++ .../ResourceHttpRequestHandlerTests.java | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 538913b16af..260b443863e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -57,6 +57,7 @@ import org.springframework.util.StringValueResolver; import org.springframework.web.HttpRequestHandler; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.context.support.ServletContextResource; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.servlet.HandlerMapping; @@ -445,6 +446,12 @@ public class ResourceHttpRequestHandler extends WebContentGenerator location = location.substring(endIndex + 1); } Resource resource = applicationContext.getResource(location); + if (location.equals("/") && !(resource instanceof ServletContextResource)) { + throw new IllegalStateException( + "The String-based location \"/\" should be relative to the web application root " + + "but resolved to a Resource of type: " + resource.getClass() + ". " + + "If this is intentional, please pass it as a pre-configured Resource via setLocations."); + } this.locationsToUse.add(resource); if (charset != null) { if (!(resource instanceof UrlResource)) { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index 38b39505f35..6ced3a30d33 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.http.HttpMethod; @@ -38,6 +39,7 @@ import org.springframework.util.StringUtils; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.accept.ContentNegotiationManagerFactoryBean; +import org.springframework.web.context.support.StaticWebApplicationContext; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import org.springframework.web.testfixture.servlet.MockHttpServletResponse; @@ -723,6 +725,25 @@ public class ResourceHttpRequestHandlerTests { assertThat(this.response.getContentAsString()).isEqualTo("h1 { color:red; }"); } + @Test + public void servletContextRootValidation() { + StaticWebApplicationContext context = new StaticWebApplicationContext() { + @Override + public Resource getResource(String location) { + return new FileSystemResource("/"); + } + }; + + ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); + handler.setLocationValues(Collections.singletonList("/")); + handler.setApplicationContext(context); + + assertThatIllegalStateException().isThrownBy(handler::afterPropertiesSet) + .withMessage("The String-based location \"/\" should be relative to the web application root but " + + "resolved to a Resource of type: class org.springframework.core.io.FileSystemResource. " + + "If this is intentional, please pass it as a pre-configured Resource via setLocations."); + } + private long resourceLastModified(String resourceName) throws IOException { return new ClassPathResource(resourceName, getClass()).getFile().lastModified();