Browse Source

Adjust error response in ResourceUrlEncodingFilter

Failure to find the lookup path now results in 400 instead of 500
reflecting the presence of some issue with the input path.

Closes gh-23508
pull/23837/head
Rossen Stoyanchev 5 years ago
parent
commit
4e4ec266b2
  1. 15
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java
  2. 10
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProviderExposingInterceptor.java
  3. 31
      spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java

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

@ -96,10 +96,7 @@ public class ResourceUrlEncodingFilter extends GenericFilterBean { @@ -96,10 +96,7 @@ public class ResourceUrlEncodingFilter extends GenericFilterBean {
String lookupPath = pathHelper.getLookupPathForRequest(this);
this.indexLookupPath = requestUri.lastIndexOf(lookupPath);
if (this.indexLookupPath == -1) {
throw new IllegalStateException(
"Failed to find lookupPath '" + lookupPath + "' within requestUri '" + requestUri + "'. " +
"Does the path have invalid encoded characters for characterEncoding '" +
getRequest().getCharacterEncoding() + "'?");
throw new LookupPathIndexException(lookupPath, requestUri);
}
this.prefixLookupPath = requestUri.substring(0, this.indexLookupPath);
if ("/".equals(lookupPath) && !"/".equals(requestUri)) {
@ -164,4 +161,14 @@ public class ResourceUrlEncodingFilter extends GenericFilterBean { @@ -164,4 +161,14 @@ public class ResourceUrlEncodingFilter extends GenericFilterBean {
}
}
@SuppressWarnings("serial")
static class LookupPathIndexException extends IllegalArgumentException {
LookupPathIndexException(String lookupPath, String requestUri) {
super("Failed to find lookupPath '" + lookupPath + "' within requestUri '" + requestUri + "'. " +
"This could be because the path has invalid encoded characters or isn't normalized.");
}
}
}

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2019 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.
@ -20,6 +20,7 @@ import javax.servlet.http.HttpServletRequest; @@ -20,6 +20,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.Assert;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/**
@ -48,7 +49,12 @@ public class ResourceUrlProviderExposingInterceptor extends HandlerInterceptorAd @@ -48,7 +49,12 @@ public class ResourceUrlProviderExposingInterceptor extends HandlerInterceptorAd
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
request.setAttribute(RESOURCE_URL_PROVIDER_ATTR, this.resourceUrlProvider);
try {
request.setAttribute(RESOURCE_URL_PROVIDER_ATTR, this.resourceUrlProvider);
}
catch (ResourceUrlEncodingFilter.LookupPathIndexException ex) {
throw new ServletRequestBindingException(ex.getMessage(), ex);
}
return true;
}

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -19,7 +19,9 @@ import java.io.IOException; @@ -19,7 +19,9 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Before;
@ -28,6 +30,7 @@ import org.junit.Test; @@ -28,6 +30,7 @@ import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockHttpServletResponse;
import org.springframework.web.bind.ServletRequestBindingException;
import static org.junit.Assert.*;
@ -155,14 +158,36 @@ public class ResourceUrlEncodingFilterTests { @@ -155,14 +158,36 @@ public class ResourceUrlEncodingFilterTests {
"/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=https://example.org#something");
}
@Test // gh-23508
public void invalidLookupPath() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/a/b/../logo.png");
request.setServletPath("/a/logo.png");
this.filter.doFilter(request, new MockHttpServletResponse(), (req, res) -> {
try {
ResourceUrlProviderExposingInterceptor interceptor =
new ResourceUrlProviderExposingInterceptor(this.urlProvider);
interceptor.preHandle((HttpServletRequest) req, (HttpServletResponse) res, new Object());
fail();
}
catch (Exception ex) {
assertEquals(ServletRequestBindingException.class, ex.getClass());
}
});
}
private void testEncodeUrl(MockHttpServletRequest request, String url, String expected)
throws ServletException, IOException {
this.filter.doFilter(request, new MockHttpServletResponse(), (req, res) -> {
FilterChain chain = (req, res) -> {
req.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.urlProvider);
String result = ((HttpServletResponse) res).encodeURL(url);
assertEquals(expected, result);
});
};
this.filter.doFilter(request, new MockHttpServletResponse(), chain);
}
}

Loading…
Cancel
Save