漏洞条件:
请求json参数不是接收参数的javabean及其父类中的任意属性。
意思就是:我javaben里面没有这个参数 你缺传递过来了 例如我只需要pageNum pageSize 你还传了role:admin 那么这样就有可能导致致特权升级、数据篡改、绕过安全机制
解决方案:
1、自建项目修复方案一:增加反序列化配置方案
1. #1、在项目的统一序列化配置中开启严格匹配模式(?如有),此处以jackson为例 2. @Configuration 3. public class JacksonConverters { 4. @Bean 5. public HttpMessageConverters JacksonHttpMessageConverters() { 6. MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter 7. = new MappingJackson2HttpMessageConverter(); 8. ObjectMapper objectMapper = new ObjectMapper(); 9. //省略其他配置开始 10. //反序列化的时候如果多了其他属性,抛出异常 11. objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); 12. //省略其他配置结束 13. } 14. } 15. 16. #2、统一异常捕获或者返回处增加非200状态码 17. /** 18. * 捕获反序列化异常HttpMessageNotReadableException,增加500状态码返回 19. * @param request 请求 20. * @param exception 异常对象 21. * @return 响应 22. */ 23. @ExceptionHandler(value = HttpMessageNotReadableException.class) 24. public ResponseEntity<Map<String, Object>> methodHttpMessageNotReadableExceptionHandler( 25. HttpServletRequest request, HttpMessageNotReadableException exception) { 26. //按需重新封装需要返回的错误信息 27. WebRequest webRequest = new ServletWebRequest(request); 28. Map<String, Object> body = errorAttributes.getErrorAttributes(webRequest, ErrorAttributeOptions.defaults()); 29. body.put(DATA, "convert exception message to JSON"); 30. body.put(STATUS, HttpStatus.INTERNAL_SERVER_ERROR.value()); 31. body.put(MESSAGE, HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); 32. body.put(SUCCESS,false); 33. return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR); 34. } 35. 36. #2、或在在其他异常拦截方法上增加状态码注解 37. @ResponseStatus()
2、自建项目修复方案二:签名验证
针对所有的请求增加参数签名,后端采用同样的方式对参数进行签名,比较前后端签名是否一致,伪代码如下:
1. #前端请求 2. 3. 请求 URL: http://localhost/cars/query 4. 请求方法: POST 5. HTTP状态码:200 6. playload:{"color":"red","company":"ltl","seats":"2-2"} #正常请求 7. Header:sign:ErOVBda4VMFdX9aixigRslAjY0rhT7lLxy 8. 9. #后端controller 10. @PostMapping(value = "/query") 11. public BaseResponse query(@RequestBody Car car){ 12. String signFront=request.header("sign"); 13. String signBackend=signUtils.handler(car); 14. if(!signBackend.equals(signFront)){ 15. throws new ServiceErrorException("签名异常"); 16. } 17. }