-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to differentiate different causes for WebInputException #28142
Comments
Can confirm that this also occurs in UnsupportedMediaTypeStatusException as well, where the implementation package name is leaked in the error reason.
|
I was also trying to find a way to tell the client that the request body missing without exposing much information. And I was able to make this work with a custom exception handler as follows. @RestControllerAdvice
public class ExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public Map<String, Object> requestBodyMissing(HttpServletRequest request) {
HandlerMethod method = (HandlerMethod) request.getAttribute("org.springframework.web.servlet.HandlerMapping.bestMatchingHandler");
String requestBody = Arrays.stream(method.getMethodParameters())
.map(m -> m.getParameterType().getSimpleName() + " " + m.getParameterName())
.collect(Collectors.joining(","));
return Arrays.stream(new Object[][] {
{"status", 400},
{"message", "Required request body is missing: " + requestBody}
}).collect(Collectors.toMap(o -> (String) o[0], o-> o[1]));
}
} When a client sends a request without a required body, it will receive something like: {
"status": 400,
"message": "Required request body is missing: String name"
} |
@ascopes thanks for creating this issue.
For validation, I see your point about Note also that for 6.0 we are making wider changes with #27052 to support problem details. This will provide more support for applications to set the response body directly from an |
@askar882 your snippet is for Spring MVC but this issue is for WebFlux. In Spring MVC there is a wider hierarchy of exceptions that make it possible to customize on a case by case basis. |
@rstoyanchev that sounds great! Look forward to seeing what comes of this, thanks for taking a look. |
I've added |
@rstoyanchev could you please tell at which version of Spring Boot |
What is the difference between |
@wimdeblauwe, one depends on the Servlet API and is used in Spring MVC. The other is part of the @dpratsun, it's available as of 6.0.0-M4. |
Looks good, thanks for taking this into consideration! |
Will this be backported to Spring 5? |
This is a request for the ability to generate a message stating that a WebFlux controller request body (or other request component) is missing, without exposing potentially sensitive implementation details in the error message. By doing this, it would remove the need for implementing a custom handler for validation where Spring provides messages that may fail organisational governance.
If we write a controller such as the following:
...the implementation for a missing request body appears to be currently defined in AbstractMessageReaderArgumentResolver:
The error message here cannot be presented to the consumer of the API on systems where governance prevents the exposure of the underlying implementation technology (this would fail penetration testing, for example). The reason for this is that the error message with the concatenated parameter info will render to something like:
This can potentially expose information allowing the inference of the underlying JDK or Spring Boot version by observing the names of the parameters and method in the underlying error, which may enable malicious actors to "comb" an API and determine if certain exploits may exist.
The issue arises that while we can override this exception with a custom exception handler, this then involves writing a significant amount of boilerplate to cater for parsing every potential binding annotation, and then extracting information such as the name of the parameter (in the case of headers), or the request body. The current API does not provide a simple way of determining that the request body is the part that is missing in this case.
If we instead use Spring Validation, and use
@RequestBody(required = false) @Valid @NotNull
, the issue will instead arise that a ConstraintViolationException is raised instead of a WebExchangeBindingException, which then requires two almost identical sets of exception handlers to achieve the same consistent validation error handling. This appears to be due tovalidate()
not being called on the body inAbstractMessageReaderArgumentResolver.java
when the body is determined to be missing.If we omit the message altogether, it leaves a response to the consumer that is not helpful for diagnosing the issue with the request. For example:
Is there a workaround for this, or is this something that could be potentially tweaked? Providing consistent validation using the Spring Validation API with WebFlux is somewhat painful at the moment because of this, and it leads to code that can be somewhat difficult to maintain when it caters for multiple edge cases.
An ideal scenario would be where we could obtain a string "type" of the parameter in question that failed validation (e.g.
"header"
,"body"
,"pathVariable"
, etc, and then a simplified message such as"Request body is required"
that can be presented back to the consumer of the API.Any help or suggestions would be greatly appreciated!
Thanks
The text was updated successfully, but these errors were encountered: