Web安全 - API 成批分配漏洞的四种修复方案

发布于:2025-02-11 ⋅ 阅读:(55) ⋅ 点赞:(0)


在这里插入图片描述


概述

在这里插入图片描述

批量分配漏洞(Mass Assignment)通常发生在后端代码使用自动数据绑定框架(如 Java 的 SpringMVC 或其他 ORM 工具)时,没有对用户输入数据进行严格验证和过滤。

例如前端用户可以通过提交额外的参数(如权限字段、敏感标志字段)绕过后端验证,将这些敏感字段意外绑定到对象中并持久化。


危害

  • 特权升级:恶意用户可以通过添加权限字段获取更高的系统权限。
  • 数据篡改:恶意篡改业务关键字段或数据,例如篡改订单状态、支付金额。
  • 绕过安全机制:可以破坏访问控制策略,导致未经授权的数据泄漏或修改。

修复建议与实施方案

解决方案 1:手动绑定数据

避免直接使用框架的自动绑定功能,改为手动提取输入参数并明确赋值。例如:

@RestController
public class RuleController {

    @PostMapping("/ruleCompletion")
    public ResponseEntity<?> ruleCompletion(@RequestBody Map<String, Object> payload) {
        Rule rule = new Rule();
        rule.setName((String) payload.get("name"));
        rule.setDescription((String) payload.get("description"));
        // 仅绑定允许的字段
        return ResponseEntity.ok(service.saveRule(rule));
    }
}

解决方案 2:使用 DTO 进行数据过滤

通过定义 DTO(数据传输对象)仅包含允许的字段,将用户输入限制为安全范围内的数据。

@Data
public class RuleDTO {
    private String name;
    private String description;
}

@RestController
public class RuleController {

    @PostMapping("/ruleCompletion")
    public ResponseEntity<?> ruleCompletion(@RequestBody RuleDTO ruleDTO) {
        Rule rule = new Rule();
        BeanUtils.copyProperties(ruleDTO, rule); // 将 DTO 数据复制到实体中
        return ResponseEntity.ok(service.saveRule(rule));
    }
}

解决方案 3:启用字段白名单

对于常见 ORM(如 Hibernate)绑定,可以启用字段白名单,指定哪些字段可以被更新:

@Entity
public class Rule {
    @Column(updatable = false)
    private Long id; // 禁止外部更新

    private String name;

    @Column(updatable = false)
    private String sensitiveField; // 禁止外部更新的敏感字段
}

解决方案 4:验证输入数据模式

结合 JSON Schema 或其他验证框架,严格定义输入数据结构。

@Component
public class RuleValidator {
    public void validate(RuleDTO ruleDTO) {
        if (StringUtils.isEmpty(ruleDTO.getName())) {
            throw new IllegalArgumentException("Name cannot be empty");
        }
        // 其他自定义验证规则
    }
}

验证修复有效性

确保修复后,以下输入无法篡改敏感数据:

  • 测试 1:尝试注入非预期字段(如 admin=true)。
  • 测试 2:尝试修改受保护字段(如 id)。
  • 测试 3:验证业务逻辑中绑定的字段是否均在允许范围内。
@Test
public void testMassAssignmentPrevention() {
    MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new RuleController()).build();
    String maliciousPayload = "{\"name\":\"test\",\"admin\":\"true\"}";
    mockMvc.perform(post("/ruleCompletion")
            .contentType(MediaType.APPLICATION_JSON)
            .content(maliciousPayload))
            .andExpect(status().isBadRequest());
}

小结

四种修复方法,包括手动绑定、DTO 使用、字段白名单和数据模式验证。

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到