Skip to content

Commit 161d3e3

Browse files
committed
Fix location checks for servlet 3 resources
SPR-12354 applied new checks to make sure that served static resources are under authorized locations. Prior to this change, serving static resources from Servlet 3 locations such as "/webjars/" would not work since those locations can be within one of the JARs on path. In that case, the checkLocation method would return false and disallow serving that static resource. This change fixes this issue by making sure to call the `ServletContextResource.getPath()` method for servlet context resources. Note that there's a known workaround for this issue, which is using a classpath scheme as location, such as: "classpath:/META-INF/resources/webjars/" instead of "/webjars". Issue: SPR-12432
1 parent 2b4004d commit 161d3e3

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.core.io.ClassPathResource;
2626
import org.springframework.core.io.Resource;
2727
import org.springframework.core.io.UrlResource;
28+
import org.springframework.web.context.support.ServletContextResource;
2829

2930
/**
3031
* A simple {@code ResourceResolver} that tries to find a resource under the given
@@ -172,6 +173,10 @@ else if (resource instanceof UrlResource) {
172173
resourcePath = resource.getURL().toExternalForm();
173174
locationPath = location.getURL().toExternalForm();
174175
}
176+
else if(resource instanceof ServletContextResource) {
177+
resourcePath = ((ServletContextResource) resource).getPath();
178+
locationPath = ((ServletContextResource) location).getPath();
179+
}
175180
else {
176181
resourcePath = resource.getURL().getPath();
177182
locationPath = location.getURL().getPath();

spring-webmvc/src/test/java/org/springframework/web/servlet/resource/PathResourceResolverTests.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515
*/
1616
package org.springframework.web.servlet.resource;
1717

18-
import static org.junit.Assert.assertEquals;
19-
import static org.junit.Assert.assertNotNull;
20-
import static org.junit.Assert.assertNull;
21-
import static org.junit.Assert.assertTrue;
18+
import static org.junit.Assert.*;
2219

2320
import java.io.IOException;
2421
import java.util.Arrays;
@@ -28,6 +25,8 @@
2825
import org.springframework.core.io.ClassPathResource;
2926
import org.springframework.core.io.Resource;
3027
import org.springframework.core.io.UrlResource;
28+
import org.springframework.mock.web.test.MockServletContext;
29+
import org.springframework.web.context.support.ServletContextResource;
3130

3231
/**
3332
* Unit tests for
@@ -93,6 +92,19 @@ public void checkResourceWithAllowedLocations() {
9392
assertEquals("../testalternatepath/bar.css", actual);
9493
}
9594

95+
// SPR-12432
96+
@Test
97+
public void checkServletContextResource() throws Exception {
98+
Resource classpathLocation = new ClassPathResource("test/", PathResourceResolver.class);
99+
MockServletContext context = new MockServletContext();
100+
101+
ServletContextResource servletContextLocation = new ServletContextResource(context, "/webjars/");
102+
ServletContextResource resource = new ServletContextResource(context, "/webjars/webjar-foo/1.0/foo.js");
103+
104+
assertFalse(this.resolver.checkResource(resource, classpathLocation));
105+
assertTrue(this.resolver.checkResource(resource, servletContextLocation));
106+
}
107+
96108
private void testCheckResource(Resource location, String requestPath) throws IOException {
97109
Resource actual = this.resolver.resolveResource(null, requestPath, Arrays.asList(location), null);
98110
assertTrue(location.createRelative(requestPath).exists());

0 commit comments

Comments
 (0)