Fix CookieRequestCache for URL encoded query parameters

Avoid populating the saved request parameters with encoded values. Since the query strings of the request and saved URL are compared and must be equal, we can just use the parameters from the incoming request.

Closes gh-9203
This commit is contained in:
Eleftheria Stein 2020-11-26 18:16:42 +01:00
parent 58e3235093
commit 7f482eda7d
2 changed files with 19 additions and 6 deletions

View File

@ -17,7 +17,6 @@
package org.springframework.security.web.savedrequest;
import java.util.Base64;
import java.util.HashMap;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
@ -79,11 +78,6 @@ public class CookieRequestCache implements RequestCache {
DefaultSavedRequest.Builder builder = new DefaultSavedRequest.Builder();
int port = getPort(uriComponents);
MultiValueMap<String, String> queryParams = uriComponents.getQueryParams();
if (!queryParams.isEmpty()) {
HashMap<String, String[]> parameters = new HashMap<>(queryParams.size());
queryParams.forEach((key, value) -> parameters.put(key, value.toArray(new String[] {})));
builder.setParameters(parameters);
}
return builder.setScheme(uriComponents.getScheme()).setServerName(uriComponents.getHost())
.setRequestURI(uriComponents.getPath()).setQueryString(uriComponents.getQuery()).setServerPort(port)
.setMethod(request.getMethod()).build();

View File

@ -153,6 +153,25 @@ public class CookieRequestCacheTests {
assertThat(expiredCookie).isNull();
}
@Test
public void matchingRequestWhenUrlEncodedQueryParametersThenDoesNotDuplicate() {
CookieRequestCache cookieRequestCache = new CookieRequestCache();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServerPort(443);
request.setSecure(true);
request.setScheme("https");
request.setServerName("abc.com");
request.setRequestURI("/destination");
request.setQueryString("goto=https%3A%2F%2Fstart.spring.io");
request.setParameter("goto", "https://start.spring.io");
String redirectUrl = "https://abc.com/destination?goto=https%3A%2F%2Fstart.spring.io";
request.setCookies(new Cookie(DEFAULT_COOKIE_NAME, encodeCookie(redirectUrl)));
MockHttpServletResponse response = new MockHttpServletResponse();
final HttpServletRequest matchingRequest = cookieRequestCache.getMatchingRequest(request, response);
assertThat(matchingRequest).isNotNull();
assertThat(matchingRequest.getParameterValues("goto")).containsExactly("https://start.spring.io");
}
@Test
public void removeRequestWhenInvokedThenSetsAnExpiredCookieOnResponse() {
CookieRequestCache cookieRequestCache = new CookieRequestCache();