如何修复Checkmarx扫描出的saveAll()不安全对象绑定漏洞?
修复Checkmarx "Unsafe object binding(不安全对象绑定)" 告警方案
Checkmarx告警内容:
The orderReqDto at src/main/java/com/coppel/omnicanal/coppelpay/controller/ValidarClienteController.java in line 69 may unintentionally allow setting the value of saveAll in validarPlazosCliente, in the object src/main/java/com/coppel/omnicanal/coppelpay/business/CustomerValidationBusiness.java at line 392.
问题根源
告警核心是:请求DTO(orderReqDto)可能通过隐式字段映射被恶意利用,修改plazosValidos集合中实体的敏感属性,进而影响saveAll()的执行逻辑。即便你的Controller仅提取了numCliente,但业务层如果存在请求DTO到数据库实体的自动/隐式映射(比如未做字段过滤的ModelMapper、MapStruct,或无限制的手动赋值),攻击者仍可构造请求体中的额外字段篡改实体属性。
具体修复方案
严格拆分请求DTO与数据库实体
确保NumClienteReqDto仅保留前端需传递的字段(仅numCliente),移除冗余字段并添加校验限制输入:public class NumClienteReqDto { @NotNull(message = "客户编号不能为空") private String numCliente; // 仅保留numCliente的getter/setter public String getNumCliente() { return numCliente; } public void setNumCliente(String numCliente) { this.numCliente = numCliente; } }禁用隐式字段映射,手动控制实体赋值
在业务层(validarPlazosCliente方法)中,禁止直接将请求DTO映射到数据库实体,改为手动提取numCliente并创建/修改实体,仅设置业务允许的字段:// 错误示例(隐式映射风险) // PlazoEntity plazo = modelMapper.map(orderReqDto, PlazoEntity.class); // 正确写法:手动赋值,仅开放允许外部传入的字段 PlazoEntity plazo = new PlazoEntity(); plazo.setNumCliente(orderReqDto.getNumCliente()); // 其他敏感字段(如状态、创建时间)由业务逻辑生成或从数据库获取 plazo.setEstado("VALIDO"); plazo.setFechaCreacion(LocalDateTime.now());限制
saveAll()的实体来源与合法性
确保plazosValidos集合中的实体均由业务逻辑主动生成/查询而来,而非从请求DTO转换。在调用saveAll()前添加校验,拦截被篡改的敏感字段:// 批量校验实体合法性 plazosValidos.forEach(plazo -> { // 禁止外部设置ID、创建时间等敏感字段 if (plazo.getId() != null) { throw new IllegalArgumentException("Plazo ID不允许外部修改"); } if (plazo.getFechaCreacion() != null) { throw new IllegalArgumentException("创建时间不允许外部修改"); } }); // 执行批量保存 clientePlazosDao.saveAll(plazosValidos);使用Builder模式创建实体(可选)
用Builder模式封装实体创建逻辑,仅暴露允许外部设置的字段,从根源避免非法赋值:PlazoEntity plazo = PlazoEntity.builder() .numCliente(orderReqDto.getNumCliente()) .estado("VALIDO") .fechaCreacion(LocalDateTime.now()) .build();
内容的提问来源于stack exchange,提问作者ParkkingMb23
相关产品推荐
相关产品推荐

