Browse Source

Sanitize request URL in ResourceUrlEncodingFilter

Prior to this change, ResourceUrlEncodingFilter and ResourceUrlProvider
would try to resolve the resource path using the full request URL (i.e.
request path and request parameters), whereas the request path is the
only information to consider.
This would lead to StringIndexOutOfBoundsExceptions when the path +
request params information was given to the AntPathMatcher.

This commit makes the appropriate change to both
ResourceUrlEncodingFilter and ResourceUrlProvider, in order to only
select the request path.

Issue: SPR-13374
pull/864/merge
Brian Clozel 11 years ago
parent
commit
0b9c3de320
  1. 11
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java
  2. 15
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java
  3. 19
      spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java
  4. 13
      spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java

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

@ -74,10 +74,12 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter { @@ -74,10 +74,12 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter {
initIndexLookupPath(resourceUrlProvider);
if (url.length() >= this.indexLookupPath) {
String prefix = url.substring(0, this.indexLookupPath);
String lookupPath = url.substring(this.indexLookupPath);
int suffixIndex = getQueryParamsIndex(url);
String suffix = url.substring(suffixIndex);
String lookupPath = url.substring(this.indexLookupPath, suffixIndex);
lookupPath = resourceUrlProvider.getForLookupPath(lookupPath);
if (lookupPath != null) {
return super.encodeURL(prefix + lookupPath);
return super.encodeURL(prefix + lookupPath + suffix);
}
}
return super.encodeURL(url);
@ -95,6 +97,11 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter { @@ -95,6 +97,11 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter {
this.indexLookupPath = requestUri.lastIndexOf(lookupPath);
}
}
private int getQueryParamsIndex(String url) {
int index = url.indexOf("?");
return index > 0 ? index : url.length();
}
}
}

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

@ -172,11 +172,13 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed @@ -172,11 +172,13 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
if (logger.isTraceEnabled()) {
logger.trace("Getting resource URL for requestURL=" + requestUrl);
}
int index = getLookupPathIndex(request);
String prefix = requestUrl.substring(0, index);
String lookupPath = requestUrl.substring(index);
int prefixIndex = getLookupPathIndex(request);
int suffixIndex = getQueryParamsIndex(requestUrl);
String prefix = requestUrl.substring(0, prefixIndex);
String suffix = requestUrl.substring(suffixIndex);
String lookupPath = requestUrl.substring(prefixIndex, suffixIndex);
String resolvedLookupPath = getForLookupPath(lookupPath);
return (resolvedLookupPath != null) ? prefix + resolvedLookupPath : null;
return (resolvedLookupPath != null) ? prefix + resolvedLookupPath + suffix : null;
}
private int getLookupPathIndex(HttpServletRequest request) {
@ -185,6 +187,11 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed @@ -185,6 +187,11 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
return requestUri.indexOf(lookupPath);
}
private int getQueryParamsIndex(String lookupPath) {
int index = lookupPath.indexOf("?");
return index > 0 ? index : lookupPath.length();
}
/**
* Compare the given path against configured resource handler mappings and
* if a match is found use the {@code ResourceResolver} chain of the matched

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -106,6 +106,23 @@ public class ResourceUrlEncodingFilterTests { @@ -106,6 +106,23 @@ public class ResourceUrlEncodingFilterTests {
});
}
// SPR-13374
@Test
public void encodeURLWithRequestParams() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
request.setContextPath("/");
request.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.resourceUrlProvider);
MockHttpServletResponse response = new MockHttpServletResponse();
this.filter.doFilterInternal(request, response, new FilterChain() {
@Override
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
String result = ((HttpServletResponse)response).encodeURL("/resources/bar.css?foo=bar&url=http://example.org");
assertEquals("/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=http://example.org", result);
}
});
}
protected ResourceUrlProvider createResourceUrlProvider(List<ResourceResolver> resolvers) {
ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler();
handler.setLocations(Arrays.asList(new ClassPathResource("test/", getClass())));

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

@ -29,6 +29,7 @@ import org.springframework.context.annotation.Bean; @@ -29,6 +29,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
@ -74,6 +75,18 @@ public class ResourceUrlProviderTests { @@ -74,6 +75,18 @@ public class ResourceUrlProviderTests {
assertEquals("/resources/foo.css", url);
}
// SPR-13374
@Test
public void getStaticResourceUrlRequestWithRequestParams() {
initTranslator();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setContextPath("/");
request.setRequestURI("/");
String url = this.translator.getForRequestUrl(request, "/resources/foo.css?foo=bar&url=http://example.org");
assertEquals("/resources/foo.css?foo=bar&url=http://example.org", url);
}
@Test
public void getFingerprintedResourceUrl() {
Map<String, VersionStrategy> versionStrategyMap = new HashMap<>();

Loading…
Cancel
Save