You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:26:24