【系统安全】appscan扫出API成批分配问题解决方案
- 工作小总结
- 时间:2023-07-04 14:09
- 3274人已阅读
简介
问题截图:原因APPScan10.0.7新增的扫描功能HCLAppScan®Enterprise中的新增功能(hcltechsw.com),增加了批量分配API的规则,导致以前系统没扫出来的问题,现在也被扫了出来。漏洞条件:1、接口类型为application/json,参数传值、form表单等类型暂未受影响。2、请求json参数不是接收参数的javabean及其父类中的任意属性。3、接口HTTP
🔔🔔🔔好消息!好消息!🔔🔔🔔
有需要的朋友👉:联系凯哥
问题截图:
原因
APPScan 10.0.7新增的扫描功能 HCL AppScan® Enterprise 中的新增功能 (hcltechsw.com),增加了批量分配API的规则,导致以前系统没扫出来的问题,现在也被扫了出来。
漏洞条件:
1、接口类型为application/json ,参数传值、form表单等类型暂未受影响。
2、请求json参数不是接收参数的javabean及其父类中的任意属性。
3、接口HTTP状态码为200
#javabean @Data public class BaseEntity{ public String tenantId; } @Data public class Car extends BaseEntity{ public String color; public String company; public String seats; } #controller @PostMapping(value = "/query") public BaseResponse query(@RequestBody Car car){ xxxxxx; } #前端请求 请求 URL: http://localhost/cars/query 请求方法: POST HTTP状态码:200 playload:{"color":"red","company":"ltl","seats":"2-2"} #正常请求 playload:{"color":"red","company":"ltl"} #正常请求 playload:{"color":"red","power":"gas"} #appscan构造的请求,power属性在Car及其父类中不存在,触发API成批分配规则
综上:此漏洞会影响目前所有的json请求接口且最近大面积扫出来是因为appscan升级所致。
解决方案:
1、自建项目修复方案一:增加反序列化配置方案
#1、在项目的统一序列化配置中开启严格匹配模式(?如有),此处以jackson为例 import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.build(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); return objectMapper; } } #2、统一异常捕获或者返回处增加非200状态码 /** * 捕获反序列化异常HttpMessageNotReadableException,增加500状态码返回 * @param request 请求 * @param exception 异常对象 * @return 响应 */ @ExceptionHandler(value = HttpMessageNotReadableException.class) public ResponseEntity<Map<String, Object>> methodHttpMessageNotReadableExceptionHandler( HttpServletRequest request, HttpMessageNotReadableException exception) { //按需重新封装需要返回的错误信息 WebRequest webRequest = new ServletWebRequest(request); Map<String, Object> body = errorAttributes.getErrorAttributes(webRequest, ErrorAttributeOptions.defaults()); body.put(DATA, "convert exception message to JSON"); body.put(STATUS, HttpStatus.INTERNAL_SERVER_ERROR.value()); body.put(MESSAGE, HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); body.put(SUCCESS,false); return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR); } #2、或在在其他异常拦截方法上增加状态码注解 @ResponseStatus()
在上述配置中,创建了一个JacksonConfig
类,并使用Jackson2ObjectMapperBuilder
构建自定义的ObjectMapper
对象。然后,将FAIL_ON_UNKNOWN_PROPERTIES
设置为true
,以启用严格验证。
请注意,这种配置方式适用于整个应用程序范围内的所有@RequestBody
参数。
2、自建项目修复方案二:签名验证
针对所有的请求增加参数签名,后端采用同样的方式对参数进行签名,比较前后端签名是否一致,伪代码如下:
#前端请求 请求 URL: http://localhost/cars/query 请求方法: POST HTTP状态码:200 playload:{"color":"red","company":"ltl","seats":"2-2"} #正常请求 Header:sign:ErOVBda4VMFdX9aixigRslAjY0rhT7lLxy #后端controller @PostMapping(value = "/query") public BaseResponse query(@RequestBody Car car){ String signFront=request.header("sign"); String signBackend=signUtils.handler(car); if(!signBackend.equals(signFront)){ throws new ServiceErrorException("签名异常"); } }