我们正在尝试解决与安全扫描相关的问题。它被视为暴露有关基础类的任何信息的漏洞。扫描程序正在向此端点发送无效数据:
@PostMapping(value = "/accountKey", params = "update")
public String accountKeyUpdate(@Valid @ModelAttribute("accountKeyForm") AccountKeyForm key, BindingResult bindingResult, Authentication authentication)
无效输入看起来像这样,其中"描述"是实体中的有效密钥,但添加" []" POST数据中属性名称的末尾导致解析错误:
description[]:
服务器返回以下内容:
{
"timestamp": "2018-04-20T14:28:36.653Z",
"status": 500,
"error": "Internal Server Error",
"message": "Invalid property 'description[]' of bean class
[com.imsweb.seerapi.account.AccountKeyForm]: Property referenced in indexed property path 'description[]' is neither an array nor a List nor a Map; returned value was []",
"path": "/accountKey/"
}
这是日志中出现的内容:
org.springframework.beans.InvalidPropertyException: Invalid property 'description[]' of bean class [com.imsweb.seerapi.account.AccountKeyForm]: Property referenced in indexed property path 'description[]' is neither an array nor a List nor a Map; returned value was []
at org.springframework.beans.AbstractNestablePropertyAccessor.processKeyedProperty(AbstractNestablePropertyAccessor.java:375) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:275) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:266) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:97) ~[spring-beans-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:839) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.validation.DataBinder.doBind(DataBinder.java:735) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:197) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:107) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.bindRequestParameters(ServletModelAttributeMethodProcessor.java:157) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:153) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:131) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
问题是我无法找到一种方法来优雅地处理无效输入。看起来当@ModelAttribute将POST主体转换为AccountKeyForm时会发生这种情况。那是在它进入控制器方法之前。我宁愿处理错误,只是将它们转发到另一页。或者如果消息说
"message": "Invalid property 'description[]'"
那也没关系。
更新:
我可以使用@ExceptionHandler来捕获该特定异常:
@ControllerAdvice
public class WebControllerAdvice {
@ExceptionHandler(InvalidPropertyException.class)
public String handleBadPropertyException() {
return "error";
}
}
这意味着我将获得一般信息。这不会引起其他类型的异常,这些异常可能会破裂。还有更好的方法吗?
更新:
这是实体类。它是一个有两个属性的简单bean。
public class AccountKeyForm {
private String _apiKey;
private String _description;
public AccountKeyForm() {
}
public AccountKeyForm(String apiKey) {
_apiKey = apiKey;
}
public AccountKeyForm(String apiKey, String description) {
_apiKey = apiKey;
_description = description;
}
public String getApiKey() {
return _apiKey;
}
public void setApiKey(String apiKey) {
_apiKey = apiKey;
}
@Size(max = 256)
public String getDescription() {
return _description;
}
public void setDescription(String description) {
_description = description;
}
}
答案 0 :(得分:1)
对此的解决方案确实是使用ControllerAdvice
来包装异常,但您需要根据需要调整响应。
因此,您应该返回一个String
和ResponseEntity
的完整httpStatus
,而不是返回body
。 body
应填充ErrorResponse
,您可以在其中定义域错误代码,如果您有类似的内容和自定义消息。
下面的代码应该有效。
@ControllerAdvice
public class WebControllerAdvice {
@ExceptionHandler(InvalidPropertyException.class)
public ResponseEntity<ErrorResponse> handle(InvalidPropertyException e) {
return ResponseEntity.status(httpStatus)
.body(new ErrorResponse(errorCode, message));
}
}
public class ErrorResponse {
private final String code;
private final String message;
public ErrorResponse(String code, String message) {
this.code = code;
this.message = message;
}
}
答案 1 :(得分:0)
它的结算说明如下
Property referenced in indexed property path 'description[]' is neither an array nor a List nor a Map; returned value was []
这意味着从请求发送的描述字段是array / List / map类型,因此,您必须更改Model类AccountKeyForm描述
从private String _description;
到private List<String> _description;
或
private Map<String> _description;
您需要确定要发送的集合类型:)
或者你必须修改请求的发送方式并确保它只发送String类型而不发送List / Map类型 前者是一个更容易的解决方案。 希望它有所帮助:)