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

如何修复Newtonsoft JSON下的Mass Assignment不安全绑定配置漏洞

Mass Assignment漏洞防范方案及Dummy字段生效原理

为什么加[JsonIgnore]的Dummy字段能消除扫描报错?

这其实是Fortify扫描规则判定逻辑导致的假修复:

  • 原始的StepDefinition类没有任何序列化控制注解(比如[JsonIgnore]、[JsonProperty]),Fortify会判定所有公开属性都可能被攻击者通过批量赋值篡改,触发漏洞告警。
  • 当你添加带[JsonIgnore]的Dummy字段后,扫描器检测到你对序列化做了显式控制,就认为你已经处理了批量赋值风险,从而停止告警。但本质上这个Dummy字段没解决实际问题——敏感字段(比如IsArchived、IsReadOnly、UserId)仍然会被Newtonsoft反序列化赋值,攻击者还是可以构造请求修改这些字段。

正确的防范方法

1. 使用DTO(数据传输对象)【最推荐】

不要直接把数据库实体类作为接口参数,专门定义只包含允许用户传入字段的DTO,严格控制输入范围,敏感的系统维护字段在Controller里手动赋值:

// 定义创建用的DTO,只暴露允许用户输入的字段
public class StepDefinitionCreateDto
{
    public string Name { get; set; }
    public string Description { get; set; }
    public bool IsAutomated { get; set; }
    public string ActionName { get; set; }
    public bool HasParameters { get; set; }
}

// 修改Controller方法
[HttpPost]
[Route("")]
public async Task<IActionResult> PostAsync(Guid tenantId, StepDefinitionCreateDto dto)
{
    // 手动将DTO字段映射到实体类,同时赋值系统字段
    var stepDefinition = new StepDefinition
    {
        TenantId = tenantId,
        Name = dto.Name,
        Description = dto.Description,
        IsAutomated = dto.IsAutomated,
        ActionName = dto.ActionName,
        HasParameters = dto.HasParameters,
        // 从当前登录用户获取UserId,避免前端传入
        UserId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)),
        // 系统默认值,不允许前端修改
        IsArchived = false,
        IsReadOnly = false,
        CanDelete = true
    };

    // 后续执行保存数据库的逻辑
    // ...
    return Ok(stepDefinition);
}

2. 显式标记允许序列化的字段

如果必须使用实体类作为参数,用Newtonsoft的注解显式指定哪些字段可以被反序列化,其他字段默认忽略:

[JsonObject(MemberSerialization.OptIn)] // 开启“仅显式标记的字段参与序列化”模式
public class StepDefinition
{
    // 这些系统字段不允许前端传入,不标记[JsonProperty]
    public Guid StepDefinitionId { get; set; }
    public Guid TenantId { get; set; }
    public bool IsArchived { get; set; }
    public bool IsReadOnly { get; set; }
    public bool CanDelete { get; set; }
    public Guid UserId { get; set; }
    public virtual ICollection<StepOutcome> StepOutComes { get; set; }

    // 允许前端传入的字段,标记[JsonProperty]
    [JsonProperty]
    public string Name { get; set; }
    
    [JsonProperty]
    public string Description { get; set; }
    
    [JsonProperty]
    public bool IsAutomated { get; set; }
    
    [JsonProperty]
    public string ActionName { get; set; }
    
    [JsonProperty]
    public bool HasParameters { get; set; }
}

3. 使用[Bind]属性限制绑定字段(不推荐)

在ASP.NET Core中,可以通过[Bind]属性指定允许模型绑定的字段,但这种方式不如DTO安全,因为实体类的所有字段仍然可见:

[HttpPost]
[Route("")]
// 只绑定指定的字段,其他字段会保持默认值
public async Task<IActionResult> PostAsync(Guid tenantId, [Bind("Name,Description,IsAutomated,ActionName,HasParameters")] StepDefinition model)
{
    // 手动赋值系统字段
    model.TenantId = tenantId;
    model.UserId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier));
    model.IsArchived = false;
    // ...

    // 后续保存逻辑
    return Ok(model);
}

内容的提问来源于stack exchange,提问作者ckv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 16:50:21