Skip to content

Commit b24e384

Browse files
committed
Prevent caching of non-document requests in HttpSessionRequestCache
When the browser requests a missing favicon.ico on the login page, it triggers an ERROR dispatch. This request was mistakenly saved and caused redirection to /error after login instead of the original URL. This change checks for DispatcherType.ERROR and Sec-Fetch-Dest header to avoid caching such requests. Closes #17686 Signed-off-by: Andrey Litvitski <[email protected]>
1 parent 1d2d268 commit b24e384

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

web/src/main/java/org/springframework/security/web/savedrequest/HttpSessionRequestCache.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.security.web.savedrequest;
1818

19+
import jakarta.servlet.DispatcherType;
1920
import jakarta.servlet.http.HttpServletRequest;
2021
import jakarta.servlet.http.HttpServletResponse;
2122
import jakarta.servlet.http.HttpSession;
@@ -38,6 +39,7 @@
3839
*
3940
* @author Luke Taylor
4041
* @author Eddú Meléndez
42+
* @author Andrey Litvitski
4143
* @since 3.0
4244
*/
4345
public class HttpSessionRequestCache implements RequestCache {
@@ -61,6 +63,17 @@ public class HttpSessionRequestCache implements RequestCache {
6163
*/
6264
@Override
6365
public void saveRequest(HttpServletRequest request, HttpServletResponse response) {
66+
boolean documentRequest = "document".equals(request.getHeader("Sec-Fetch-Dest"));
67+
boolean dispatchError = DispatcherType.ERROR.equals(request.getDispatcherType());
68+
69+
if (!documentRequest && dispatchError) {
70+
if (this.logger.isTraceEnabled()) {
71+
this.logger
72+
.trace("Did not save request because it is an ERROR dispatcher and not a primary document request");
73+
}
74+
return;
75+
}
76+
6477
if (!this.requestMatcher.matches(request)) {
6578
if (this.logger.isTraceEnabled()) {
6679
this.logger

web/src/test/java/org/springframework/security/web/savedrequest/HttpSessionRequestCacheTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.Locale;
2222
import java.util.Map;
2323

24+
import jakarta.servlet.DispatcherType;
2425
import jakarta.servlet.http.Cookie;
2526
import jakarta.servlet.http.HttpServletRequest;
2627
import jakarta.servlet.http.HttpServletResponse;
@@ -40,6 +41,7 @@
4041
/**
4142
* @author Luke Taylor
4243
* @author Eddú Meléndez
44+
* @author Andrey Litvitski
4345
* @since 3.0
4446
*/
4547
public class HttpSessionRequestCacheTests {
@@ -168,6 +170,18 @@ public void getMatchingRequestWhenMatchingRequestParameterNameSetThenDoesNotInvo
168170
verify(request, never()).getParameterMap();
169171
}
170172

173+
// gh-17686
174+
@Test
175+
public void saveRequestShouldNotSaveRequestWhenErrorDispatcherAndNonDocumentRequest() {
176+
HttpSessionRequestCache cache = new HttpSessionRequestCache();
177+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/destination");
178+
request.setDispatcherType(DispatcherType.ERROR);
179+
request.addHeader("Sec-Fetch-Dest", "image");
180+
MockHttpServletResponse response = new MockHttpServletResponse();
181+
cache.saveRequest(request, response);
182+
assertThat(request.getSession().getAttribute(HttpSessionRequestCache.SAVED_REQUEST)).isNull();
183+
}
184+
171185
private static final class CustomSavedRequest implements SavedRequest {
172186

173187
private final SavedRequest delegate;

0 commit comments

Comments
 (0)