VYPR
High severityNVD Advisory· Published May 26, 2023· Updated Jan 16, 2025

CVE-2023-20883

CVE-2023-20883

Description

Spring Boot vulnerable to DoS via welcome page 404 caching when used with a reverse proxy; fixed by returning 406.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Spring Boot vulnerable to DoS via welcome page 404 caching when used with a reverse proxy; fixed by returning 406.

In Spring Boot versions 3.0.0–3.0.6, 2.7.0–2.7.11, 2.6.0–2.6.14, 2.5.0–2.5.14, and older unsupported versions, the welcome page handler could return an HTTP 404 status when it was unable to produce an acceptable response (e.g., due to an incompatible client Accept header) [1][3]. If a reverse proxy cache is deployed in front of the application, this 404 response could be cached and served to subsequent legitimate requests, resulting in a denial-of-service (DoS) condition [1].

An attacker can exploit this by sending a crafted request with an Accept header that the welcome page cannot satisfy, triggering the erroneous 404 response [2][3]. No authentication or special privileges are required; only network access to the application is needed. Once the reverse proxy caches the 404, all following users requesting the welcome page receive the cached error, effectively denying access [3].

The impact is a DoS where legitimate users are unable to reach the welcome page, which may be the entry point for the application and could disrupt normal operations or user experience.

Spring Boot addressed the issue by modifying the welcome page handler to return HTTP 406 Not Acceptable instead of 404 [2]. HTTP 406 is not cacheable by default, preventing reverse proxies from caching the error. Patched releases include versions 2.7.12, 3.0.7, and later [4]. Users should upgrade to a fixed version or configure their reverse proxy not to cache 404 responses from the application.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.springframework.boot:spring-boot-autoconfigureMaven
>= 3.0.0, < 3.0.73.0.7
org.springframework.boot:spring-boot-autoconfigureMaven
>= 2.7.0, < 2.7.122.7.12
org.springframework.boot:spring-boot-autoconfigureMaven
>= 2.6.0, < 2.6.152.6.15
org.springframework.boot:spring-boot-autoconfigureMaven
< 2.5.152.5.15

Affected products

2

Patches

1
418dd1ba5bda

Return 406 status code if welcome page is not accepted

https://github.com/spring-projects/spring-bootPhillip WebbMay 15, 2023via ghsa
8 files changed · +356 42
  • spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java+39 12 modified
    @@ -108,6 +108,7 @@
     import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
     import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
     import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
    +import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
     import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
     import org.springframework.web.servlet.i18n.FixedLocaleResolver;
     import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
    @@ -437,12 +438,29 @@ protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
     		@Bean
     		public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
     				FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
    -			WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
    -					new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
    -					this.mvcProperties.getStaticPathPattern());
    -			welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
    -			welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
    -			return welcomePageHandlerMapping;
    +			return createWelcomePageHandlerMapping(applicationContext, mvcConversionService, mvcResourceUrlProvider,
    +					WelcomePageHandlerMapping::new);
    +		}
    +
    +		@Bean
    +		public WelcomePageNotAcceptableHandlerMapping welcomePageNotAcceptableHandlerMapping(
    +				ApplicationContext applicationContext, FormattingConversionService mvcConversionService,
    +				ResourceUrlProvider mvcResourceUrlProvider) {
    +			return createWelcomePageHandlerMapping(applicationContext, mvcConversionService, mvcResourceUrlProvider,
    +					WelcomePageNotAcceptableHandlerMapping::new);
    +		}
    +
    +		private <T extends AbstractUrlHandlerMapping> T createWelcomePageHandlerMapping(
    +				ApplicationContext applicationContext, FormattingConversionService mvcConversionService,
    +				ResourceUrlProvider mvcResourceUrlProvider, WelcomePageHandlerMappingFactory<T> factory) {
    +			TemplateAvailabilityProviders templateAvailabilityProviders = new TemplateAvailabilityProviders(
    +					applicationContext);
    +			String staticPathPattern = this.mvcProperties.getStaticPathPattern();
    +			T handlerMapping = factory.create(templateAvailabilityProviders, applicationContext, getIndexHtmlResource(),
    +					staticPathPattern);
    +			handlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
    +			handlerMapping.setCorsConfigurations(getCorsConfigurations());
    +			return handlerMapping;
     		}
     
     		@Override
    @@ -471,25 +489,25 @@ public FlashMapManager flashMapManager() {
     			return super.flashMapManager();
     		}
     
    -		private Resource getWelcomePage() {
    +		private Resource getIndexHtmlResource() {
     			for (String location : this.resourceProperties.getStaticLocations()) {
    -				Resource indexHtml = getIndexHtml(location);
    +				Resource indexHtml = getIndexHtmlResource(location);
     				if (indexHtml != null) {
     					return indexHtml;
     				}
     			}
     			ServletContext servletContext = getServletContext();
     			if (servletContext != null) {
    -				return getIndexHtml(new ServletContextResource(servletContext, SERVLET_LOCATION));
    +				return getIndexHtmlResource(new ServletContextResource(servletContext, SERVLET_LOCATION));
     			}
     			return null;
     		}
     
    -		private Resource getIndexHtml(String location) {
    -			return getIndexHtml(this.resourceLoader.getResource(location));
    +		private Resource getIndexHtmlResource(String location) {
    +			return getIndexHtmlResource(this.resourceLoader.getResource(location));
     		}
     
    -		private Resource getIndexHtml(Resource location) {
    +		private Resource getIndexHtmlResource(Resource location) {
     			try {
     				Resource resource = location.createRelative("index.html");
     				if (resource.exists() && (resource.getURL() != null)) {
    @@ -603,6 +621,15 @@ ResourceChainResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCu
     
     	}
     
    +	@FunctionalInterface
    +	interface WelcomePageHandlerMappingFactory<T extends AbstractUrlHandlerMapping> {
    +
    +		T create(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext,
    +				Resource indexHtmlResource, String staticPathPattern);
    +
    +	}
    +
    +	@FunctionalInterface
     	interface ResourceHandlerRegistrationCustomizer {
     
     		void customize(ResourceHandlerRegistration registration);
    
  • spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMapping.java+22 26 modified
    @@ -1,5 +1,5 @@
     /*
    - * Copyright 2012-2021 the original author or authors.
    + * Copyright 2012-2023 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.
    @@ -27,19 +27,21 @@
     import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
     import org.springframework.context.ApplicationContext;
     import org.springframework.core.io.Resource;
    +import org.springframework.core.log.LogMessage;
     import org.springframework.http.HttpHeaders;
     import org.springframework.http.MediaType;
     import org.springframework.util.StringUtils;
     import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
     import org.springframework.web.servlet.mvc.ParameterizableViewController;
     
     /**
    - * An {@link AbstractUrlHandlerMapping} for an application's welcome page. Supports both
    - * static and templated files. If both a static and templated index page are available,
    - * the static page is preferred.
    + * An {@link AbstractUrlHandlerMapping} for an application's HTML welcome page. Supports
    + * both static and templated files. If both a static and templated index page are
    + * available, the static page is preferred.
      *
      * @author Andy Wilkinson
      * @author Bruce Brouwer
    + * @see WelcomePageNotAcceptableHandlerMapping
      */
     final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping {
     
    @@ -48,37 +50,31 @@ final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping {
     	private static final List<MediaType> MEDIA_TYPES_ALL = Collections.singletonList(MediaType.ALL);
     
     	WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
    -			ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
    -		if (welcomePage != null && "/**".equals(staticPathPattern)) {
    -			logger.info("Adding welcome page: " + welcomePage);
    -			setRootViewName("forward:index.html");
    -		}
    -		else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
    -			logger.info("Adding welcome page template: index");
    -			setRootViewName("index");
    -		}
    -	}
    -
    -	private boolean welcomeTemplateExists(TemplateAvailabilityProviders templateAvailabilityProviders,
    -			ApplicationContext applicationContext) {
    -		return templateAvailabilityProviders.getProvider("index", applicationContext) != null;
    -	}
    -
    -	private void setRootViewName(String viewName) {
    -		ParameterizableViewController controller = new ParameterizableViewController();
    -		controller.setViewName(viewName);
    -		setRootHandler(controller);
    +			ApplicationContext applicationContext, Resource indexHtmlResource, String staticPathPattern) {
     		setOrder(2);
    +		WelcomePage welcomePage = WelcomePage.resolve(templateAvailabilityProviders, applicationContext,
    +				indexHtmlResource, staticPathPattern);
    +		if (welcomePage != WelcomePage.UNRESOLVED) {
    +			logger.info(LogMessage.of(() -> (!welcomePage.isTemplated()) ? "Adding welcome page: " + indexHtmlResource
    +					: "Adding welcome page template: index"));
    +			ParameterizableViewController controller = new ParameterizableViewController();
    +			controller.setViewName(welcomePage.getViewName());
    +			setRootHandler(controller);
    +		}
     	}
     
     	@Override
     	public Object getHandlerInternal(HttpServletRequest request) throws Exception {
    +		return (!isHtmlTextAccepted(request)) ? null : super.getHandlerInternal(request);
    +	}
    +
    +	private boolean isHtmlTextAccepted(HttpServletRequest request) {
     		for (MediaType mediaType : getAcceptedMediaTypes(request)) {
     			if (mediaType.includes(MediaType.TEXT_HTML)) {
    -				return super.getHandlerInternal(request);
    +				return true;
     			}
     		}
    -		return null;
    +		return false;
     	}
     
     	private List<MediaType> getAcceptedMediaTypes(HttpServletRequest request) {
    
  • spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePage.java+79 0 added
    @@ -0,0 +1,79 @@
    +/*
    + * Copyright 2012-2023 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.
    + * You may obtain a copy of the License at
    + *
    + *      https://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.springframework.boot.autoconfigure.web.servlet;
    +
    +import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
    +import org.springframework.context.ApplicationContext;
    +import org.springframework.core.io.Resource;
    +
    +/**
    + * Details for a welcome page resolved from a resource or a template.
    + *
    + * @author Phillip Webb
    + */
    +final class WelcomePage {
    +
    +	/**
    +	 * Value used for an unresolved welcome page.
    +	 */
    +	static final WelcomePage UNRESOLVED = new WelcomePage(null, false);
    +
    +	private final String viewName;
    +
    +	private final boolean templated;
    +
    +	private WelcomePage(String viewName, boolean templated) {
    +		this.viewName = viewName;
    +		this.templated = templated;
    +	}
    +
    +	/**
    +	 * Return the view name of the welcome page.
    +	 * @return the view name
    +	 */
    +	String getViewName() {
    +		return this.viewName;
    +	}
    +
    +	/**
    +	 * Return if the welcome page is from a template.
    +	 * @return if the welcome page is templated
    +	 */
    +	boolean isTemplated() {
    +		return this.templated;
    +	}
    +
    +	/**
    +	 * Resolve the {@link WelcomePage} to use.
    +	 * @param templateAvailabilityProviders the template availability providers
    +	 * @param applicationContext the application context
    +	 * @param indexHtmlResource the index HTML resource to use or {@code null}
    +	 * @param staticPathPattern the static path pattern being used
    +	 * @return a resolved {@link WelcomePage} instance or {@link #UNRESOLVED}
    +	 */
    +	static WelcomePage resolve(TemplateAvailabilityProviders templateAvailabilityProviders,
    +			ApplicationContext applicationContext, Resource indexHtmlResource, String staticPathPattern) {
    +		if (indexHtmlResource != null && "/**".equals(staticPathPattern)) {
    +			return new WelcomePage("forward:index.html", false);
    +		}
    +		if (templateAvailabilityProviders.getProvider("index", applicationContext) != null) {
    +			return new WelcomePage("index", true);
    +		}
    +		return UNRESOLVED;
    +	}
    +
    +}
    
  • spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMapping.java+58 0 added
    @@ -0,0 +1,58 @@
    +/*
    + * Copyright 2012-2023 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.
    + * You may obtain a copy of the License at
    + *
    + *      https://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.springframework.boot.autoconfigure.web.servlet;
    +
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
    +
    +import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
    +import org.springframework.context.ApplicationContext;
    +import org.springframework.core.io.Resource;
    +import org.springframework.http.HttpStatus;
    +import org.springframework.web.servlet.ModelAndView;
    +import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
    +import org.springframework.web.servlet.mvc.Controller;
    +
    +/**
    + * An {@link AbstractUrlHandlerMapping} for an application's welcome page that was
    + * ultimately not accepted.
    + *
    + * @author Phillip Webb
    + */
    +class WelcomePageNotAcceptableHandlerMapping extends AbstractUrlHandlerMapping {
    +
    +	WelcomePageNotAcceptableHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
    +			ApplicationContext applicationContext, Resource indexHtmlResource, String staticPathPattern) {
    +		setOrder(LOWEST_PRECEDENCE - 10); // Before ResourceHandlerRegistry
    +		WelcomePage welcomePage = WelcomePage.resolve(templateAvailabilityProviders, applicationContext,
    +				indexHtmlResource, staticPathPattern);
    +		if (welcomePage != WelcomePage.UNRESOLVED) {
    +			setRootHandler((Controller) this::handleRequest);
    +		}
    +	}
    +
    +	private ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
    +		response.setStatus(HttpStatus.NOT_ACCEPTABLE.value());
    +		return null;
    +	}
    +
    +	@Override
    +	protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
    +		return super.getHandlerInternal(request);
    +	}
    +
    +}
    
  • spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java+3 3 modified
    @@ -169,7 +169,7 @@ void handlerAdaptersCreated() {
     
     	@Test
     	void handlerMappingsCreated() {
    -		this.contextRunner.run((context) -> assertThat(context).getBeans(HandlerMapping.class).hasSize(5));
    +		this.contextRunner.run((context) -> assertThat(context).getBeans(HandlerMapping.class).hasSize(6));
     	}
     
     	@Test
    @@ -687,8 +687,8 @@ void welcomePageHandlerMappingIsAutoConfigured() {
     		this.contextRunner.withPropertyValues("spring.web.resources.static-locations:classpath:/welcome-page/")
     			.run((context) -> {
     				assertThat(context).hasSingleBean(WelcomePageHandlerMapping.class);
    -				WelcomePageHandlerMapping bean = context.getBean(WelcomePageHandlerMapping.class);
    -				assertThat(bean.getRootHandler()).isNotNull();
    +				assertThat(context.getBean(WelcomePageHandlerMapping.class).getRootHandler()).isNotNull();
    +				assertThat(context.getBean(WelcomePageNotAcceptableHandlerMapping.class).getRootHandler()).isNotNull();
     			});
     	}
     
    
  • spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMappingTests.java+0 1 modified
    @@ -116,7 +116,6 @@ void handlesRequestWithEmptyAcceptHeader() {
     				.perform(get("/").header(HttpHeaders.ACCEPT, ""))
     				.andExpect(status().isOk())
     				.andExpect(forwardedUrl("index.html")));
    -
     	}
     
     	@Test
    
  • spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java+11 0 modified
    @@ -29,6 +29,7 @@
     import org.springframework.boot.test.web.server.LocalServerPort;
     import org.springframework.context.annotation.Configuration;
     import org.springframework.context.annotation.Import;
    +import org.springframework.http.HttpStatus;
     import org.springframework.http.MediaType;
     import org.springframework.http.RequestEntity;
     import org.springframework.http.ResponseEntity;
    @@ -57,6 +58,16 @@ void contentStrategyWithWelcomePage() throws Exception {
     			.build();
     		ResponseEntity<String> content = this.template.exchange(entity, String.class);
     		assertThat(content.getBody()).contains("/custom-");
    +		assertThat(content.getStatusCode()).isEqualTo(HttpStatus.OK);
    +	}
    +
    +	@Test
    +	void notAcceptableWelcomePage() throws Exception {
    +		RequestEntity<?> entity = RequestEntity.get(new URI("http://localhost:" + this.port + "/"))
    +			.header("Accept", "spring/boot")
    +			.build();
    +		ResponseEntity<String> content = this.template.exchange(entity, String.class);
    +		assertThat(content.getStatusCode()).isEqualTo(HttpStatus.NOT_ACCEPTABLE);
     	}
     
     	@Configuration
    
  • spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMappingTests.java+144 0 added
    @@ -0,0 +1,144 @@
    +/*
    + * Copyright 2012-2023 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.
    + * You may obtain a copy of the License at
    + *
    + *      https://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.springframework.boot.autoconfigure.web.servlet;
    +
    +import org.junit.jupiter.api.Test;
    +
    +import org.springframework.beans.factory.ObjectProvider;
    +import org.springframework.beans.factory.annotation.Value;
    +import org.springframework.boot.autoconfigure.AutoConfigurations;
    +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
    +import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
    +import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
    +import org.springframework.context.ApplicationContext;
    +import org.springframework.context.annotation.Bean;
    +import org.springframework.context.annotation.Configuration;
    +import org.springframework.core.Ordered;
    +import org.springframework.core.io.FileSystemResource;
    +import org.springframework.core.io.Resource;
    +import org.springframework.http.HttpHeaders;
    +import org.springframework.http.MediaType;
    +import org.springframework.test.util.ReflectionTestUtils;
    +import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    +
    +import static org.assertj.core.api.Assertions.assertThat;
    +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    +
    +/**
    + * Tests for {@link WelcomePageNotAcceptableHandlerMapping}.
    + *
    + * @author Phillip Webb
    + */
    +class WelcomePageNotAcceptableHandlerMappingTests {
    +
    +	private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
    +		.withUserConfiguration(HandlerMappingConfiguration.class)
    +		.withConfiguration(AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class));
    +
    +	@Test
    +	void isOrderedAtLowPriorityButAboveResourceHandlerRegistry() {
    +		this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class).run((context) -> {
    +			WelcomePageNotAcceptableHandlerMapping handler = context
    +				.getBean(WelcomePageNotAcceptableHandlerMapping.class);
    +			ResourceHandlerRegistry registry = new ResourceHandlerRegistry(context, null);
    +			Integer resourceOrder = (Integer) ReflectionTestUtils.getField(registry, "order");
    +			assertThat(handler.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE - 10);
    +			assertThat(handler.getOrder()).isLessThan(resourceOrder);
    +		});
    +	}
    +
    +	@Test
    +	void handlesRequestForStaticPageThatAcceptsTextHtml() {
    +		this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
    +			.run((context) -> MockMvcBuilders.webAppContextSetup(context)
    +				.build()
    +				.perform(get("/").accept(MediaType.TEXT_HTML))
    +				.andExpect(status().isNotAcceptable()));
    +	}
    +
    +	@Test
    +	void handlesRequestForStaticPagetThatDoesNotAcceptTextHtml() {
    +		this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
    +			.run((context) -> MockMvcBuilders.webAppContextSetup(context)
    +				.build()
    +				.perform(get("/").accept(MediaType.APPLICATION_JSON))
    +				.andExpect(status().isNotAcceptable()));
    +	}
    +
    +	@Test
    +	void handlesRequestWithNoAcceptHeader() {
    +		this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
    +			.run((context) -> MockMvcBuilders.webAppContextSetup(context)
    +				.build()
    +				.perform(get("/"))
    +				.andExpect(status().isNotAcceptable()));
    +	}
    +
    +	@Test
    +	void handlesRequestWithEmptyAcceptHeader() {
    +		this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
    +			.run((context) -> MockMvcBuilders.webAppContextSetup(context)
    +				.build()
    +				.perform(get("/").header(HttpHeaders.ACCEPT, ""))
    +				.andExpect(status().isNotAcceptable()));
    +	}
    +
    +	@Test
    +	void rootHandlerIsNotRegisteredWhenStaticPathPatternIsNotSlashStarStar() {
    +		this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
    +			.withPropertyValues("static-path-pattern=/foo/**")
    +			.run((context) -> assertThat(context.getBean(WelcomePageNotAcceptableHandlerMapping.class).getRootHandler())
    +				.isNull());
    +	}
    +
    +	@Test
    +	void producesNotFoundResponseWhenThereIsNoWelcomePage() {
    +		this.contextRunner.run((context) -> MockMvcBuilders.webAppContextSetup(context)
    +			.build()
    +			.perform(get("/").accept(MediaType.TEXT_HTML))
    +			.andExpect(status().isNotFound()));
    +	}
    +
    +	@Configuration(proxyBeanMethods = false)
    +	static class HandlerMappingConfiguration {
    +
    +		@Bean
    +		WelcomePageNotAcceptableHandlerMapping handlerMapping(ApplicationContext applicationContext,
    +				ObjectProvider<TemplateAvailabilityProviders> templateAvailabilityProviders,
    +				ObjectProvider<Resource> staticIndexPage,
    +				@Value("${static-path-pattern:/**}") String staticPathPattern) {
    +			return new WelcomePageNotAcceptableHandlerMapping(
    +					templateAvailabilityProviders
    +						.getIfAvailable(() -> new TemplateAvailabilityProviders(applicationContext)),
    +					applicationContext, staticIndexPage.getIfAvailable(), staticPathPattern);
    +		}
    +
    +	}
    +
    +	@Configuration(proxyBeanMethods = false)
    +	static class StaticResourceConfiguration {
    +
    +		@Bean
    +		Resource staticIndexPage() {
    +			return new FileSystemResource("src/test/resources/welcome-page/index.html");
    +		}
    +
    +	}
    +
    +}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.