Check viewName for special prefixes in UrlFilenameViewController

Closes gh-37027
This commit is contained in:
rstoyanchev
2026-08-14 09:11:50 +02:00
committed by Brian Clozel
parent a784dbe286
commit b9379e33d5
2 changed files with 34 additions and 1 deletions
@@ -22,8 +22,11 @@ import java.util.concurrent.ConcurrentHashMap;
import jakarta.servlet.http.HttpServletRequest;
import org.jspecify.annotations.Nullable;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import org.springframework.web.util.ServletRequestPathUtils;
/**
@@ -150,7 +153,16 @@ public class UrlFilenameViewController extends AbstractUrlViewController {
* @see #getSuffix()
*/
protected String postProcessViewName(String viewName) {
return getPrefix() + viewName + getSuffix();
return checkViewName(getPrefix() + viewName + getSuffix(), viewName);
}
private static String checkViewName(String viewNameToUse, String originalViewName) {
if (viewNameToUse.startsWith(UrlBasedViewResolver.REDIRECT_URL_PREFIX) ||
viewNameToUse.startsWith(UrlBasedViewResolver.FORWARD_URL_PREFIX)) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, "Rejected viewName '" + originalViewName + "'");
}
return viewNameToUse;
}
}
@@ -22,8 +22,10 @@ import java.util.stream.Stream;
import org.junit.jupiter.api.Named;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.ui.ModelMap;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
@@ -34,6 +36,7 @@ import org.springframework.web.testfixture.servlet.MockHttpServletResponse;
import org.springframework.web.util.ServletRequestPathUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Juergen Hoeller
@@ -75,6 +78,24 @@ class UrlFilenameViewControllerTests {
assertThat(mv.getModel()).isEmpty();
}
@PathPatternsParameterizedTest
void withRedirectPrefix(Function<String, MockHttpServletRequest> requestFactory) {
UrlFilenameViewController controller = new UrlFilenameViewController();
MockHttpServletRequest request = requestFactory.apply("/redirect:index");
assertThatExceptionOfType(ResponseStatusException.class)
.isThrownBy(() -> controller.handleRequest(request, new MockHttpServletResponse()))
.satisfies(ex -> assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST));
}
@PathPatternsParameterizedTest
void withForwardPrefix(Function<String, MockHttpServletRequest> requestFactory) {
UrlFilenameViewController controller = new UrlFilenameViewController();
MockHttpServletRequest request = requestFactory.apply("/forward:index");
assertThatExceptionOfType(ResponseStatusException.class)
.isThrownBy(() -> controller.handleRequest(request, new MockHttpServletResponse()))
.satisfies(ex -> assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST));
}
@PathPatternsParameterizedTest
void withPrefixAndSuffix(Function<String, MockHttpServletRequest> requestFactory) throws Exception {
UrlFilenameViewController controller = new UrlFilenameViewController();