5

I have several SprigMVC methods like this below, returning either a ModelAndView or a Responsebody. When users makes a request to these urls missing the required parameters they naturally get the message "Required String parameter 'id' is not present".

From security perspective I want to hide this detailed description messages from users. So a hacker don't easily know the missing parameters and will get a 400 error without any description. Is this possible via a spring configuration/Spring Security or I have to manually refactor all my methods to return a custom message somehow.

@RequestMapping(value = "/payment", method = RequestMethod.GET)
public ModelAndView getReponse(@RequestParam(value = "id", required = true)) {

    return model;
}

@RequestMapping(value = "/status", method = RequestMethod.GET)
public @ResponseBody String getStatus(@RequestParam(value = "id", required = true) String id) {

    return "string";
}
6
  • So bypassing that error will also help right? Commented Oct 28, 2015 at 8:52
  • @Rehman not sure what you mean by bypass but probably Commented Oct 28, 2015 at 8:56
  • Now its clear after editing your question. I was thinking about required=false. But you want 400 Commented Oct 28, 2015 at 8:57
  • 1
    can you show your web.xml? particularly the error-page part, if you have it configured (some examples here stackoverflow.com/questions/7066192/…) Commented Oct 28, 2015 at 9:02
  • 1
    You can use @ExceptionHandler. Here is a an example how to use it stackoverflow.com/questions/13356549/… Commented Oct 28, 2015 at 9:03

2 Answers 2

9

What you actually need is a global handler for MissingServletRequestParameterException, which is thrown by Spring when a request parameter is missing. The easiest way to tackle this problem is to use ControllerAdvice that will handle it for all your controllers.

import org.springframework.web.bind.MissingServletRequestParameterException;

@ControllerAdvice
class MissingServletRequestParameterExceptionHandler {
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handleMissingParameter() {
        return "Your custom result";
    }
}

If you want to hide the missing parameter message only for a particular controller, just move handleMissingParameter method to this controller without creating the ControllerAdvice.

Sign up to request clarification or add additional context in comments.

4 Comments

tnx. does this approach has any advantage over using <error-page> in my web.xml? I just tried and I could show my own custom error page for all 400 errors
If you just want to display a simple error page then no, <error-page> is sufficient. But you can use this handler to log such a situation and since you wrote about attacks that information may be interesting for you.
yes indeed for logging! tnx but its not clear how can I use it for a single controller method? And is there a way to get the HttpRequest object for detailed logging
@ExceptionHandler works on the class level. If you put it inside a controller class, it handles specified exception for all methods inside this class. Unfortunately, it's not possible to choose only a selected method. You need some custom solution, e.g., pass a request to the handler method and verify whether for that URL you should execute the handler or re-throw the exception.
4

I personally upvoted Daniel Olszewski's answer because it's hip, nice, concise and readable, although in a customer-facing, publicly available site (when you go beyond the fast prototyping with Spring Boot phase and need to be perfectly sure that nothing gets through) one may want to use it together with the plain-old error-page in web.xml approach (some examples here: Handle error 404 with Spring controller).

It may not be fun (I, personally, despise anything XML related beyond explainability), but (unless you're not using web.xml at all in favor of WebApplicationInitializer), web.xml is almost the lowest layer in a web app and no error page (no matter the exception or URL mapping) will get through it, just remember to map all the HTTP status codes (i.e. have one default error-page element without the child error-code element).

The solution for WebApplicationInitializer is analogous, some xamples here: Using Spring MVC 3.1+ WebApplicationInitializer to programmatically configure session-config and error-page.

The lowest layer approach would be to set the error page contener-wide, e.g. for Tomcat: http://linux-sxs.org/internet_serving/c581.html.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.