0

I have a spring-boot 1.3.0-BUILD-SNAPSHOT w/SpringSecurity project and I am concerned about security of the REST endpoints. I have a CORS Filter defined:

@Configuration
public class CorsConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {

        return new WebMvcConfigurerAdapter() {

            @Override
            public void addCorsMappings(CorsRegistry registry) {

                registry.addMapping( "/**" ).allowedOrigins( "*" )
                        .allowedHeaders( "Access-Control-Allow-Origin", "*"          )       "x-requested-with" )
                        .allowedHeaders("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
                        .allowedMethods("GET", "POST", "PUT", "DELETE")
                        .allowedMethods("Access-Control-Allow-Headers", "Content-Type")
                        .maxAge( 3600);

            }

        };
    }
}

And I have a REST Controller:

@Controller
@Transactional
public class Controller extends BaseController {

    @Autowired
    private QuestionService questionService;

    @RequestMapping(value = "/questions", method = RequestMethod.GET)
    @ResponseBody
    public List<Question> getAllQuestions() {
        return questionService.getAllAvailableQuestions();
    }

  ...
}

But when I hit one of the endpoints with an OPTIONS call I get a result that appears to allow more than just the GET this endpoint defines:

Allow → GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control → no-cache, no-store, max-age=0, must-revalidate
Content-Length → 0
Date → Wed, 28 Oct 2015 16:32:12 GMT
Expires → 0
Pragma → no-cache
Server → Apache-Coyote/1.1
X-CSRF-HEADER → X-CSRF-TOKEN
X-CSRF-PARAM → _csrf
X-CSRF-TOKEN → 83983056-f904-449e-a215-fe9f9492866b
X-Content-Type-Options → nosniff
X-Frame-Options → DENY
X-XSS-Protection → 1; mode=block

I thought Spring MVC would ignore OPTIONS call by default. But I guess I also don't understand why I am seeing Allow → GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH being returned when I only allow GET for that call. In the entire application I only allow GET, PUT, POST, DELETE so I don't know why the other values are returned, and what that means. And most importantly, is this a security vulnerability?

Jonik
  • 80,077
  • 70
  • 264
  • 372
sonoerin
  • 5,015
  • 23
  • 75
  • 132
  • Nothing in your question is about Spring Security so far. What does your call look like? Why should Spring ignore `OPTIONS` by default and how is that supposed to work with CORS, where `OPTIONS` is needed? What makes the response you get a security problem? And where and how did you define that only GET, PUT, POST, DELETE are allowed? `addCorsMappings` is only about CORS, nothing else. – a better oliver Oct 28 '15 at 17:23
  • Yea, I am still learning what all this means after going thru a security review. I mentioned Spring Security because the project contains it and I thought it might be relevant to this topic. I had done some research and read that OPTIONS was ignored by default, but perhaps that was a bad link. In my CORS configuration I only allow those 4 methods, which is why I don't understand why the OPTIONS is saying that "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH" is allowed when CORS and my own REST endpoints don't use them all. – sonoerin Oct 29 '15 at 13:51
  • 1
    CORS is only relevant for browsers (i.e. AJAX!) and the CORS related response headers all start with `Access-Control-`. The controller can only handle `GET` requests for `/questions`. So if you don't have any other handler for that URL, an error will be returned for every other request method. And that's true for every request: No appropriate handler -> status 4xx. – a better oliver Oct 29 '15 at 16:28
  • Thank you, that helps me understand better. – sonoerin Oct 29 '15 at 22:06

2 Answers2

3

If you take a look at JavaDoc of BaseFrameworkServlet#setDispatchOptionsRequest() it contains following comment:

Set whether this servlet should dispatch an HTTP OPTIONS request to the #doService method Default is "false", applying javax.servlet.http.HttpServlet's default behavior (i.e. enumerating all standard HTTP request methods as a response to the OPTIONS request).


But I guess I also don't understand why I am seeing Allow → GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH being returned when I only allow GET for that call.

As mentioned in the comment above, the request is not handled by Spring MVC dispatcher, but by HttpServletRequest#doOptions, which enumerates HTTP methods the server supports and knows nothing about your controller mapping.

If you want to verify this behavior you can put breakpoints in DispatcherServlet's doService method and HttpServlets doOptions method and see which one gets called. If you want OPTIONS request to be handled by the dispatcher, you can enable it using one of the ways described here.

Community
  • 1
  • 1
Bohuslav Burghardt
  • 33,626
  • 7
  • 114
  • 109
0

For Spring Boot application add to the application.properties file the following property:

spring.mvc.dispatch-options-request=true

It will do the job.

perbellinio
  • 682
  • 5
  • 14