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

Json.NET反序列化接口属性报无法实例化错误,如何安全解决?

可行的无安全风险解决方案

方案1:单实现场景用自定义JsonConverter固定映射

如果你的ISomething接口只有一个固定的实现类,直接自定义JsonConverter明确指定实现类型即可,完全不需要开启TypeNameHandling,所有实例化逻辑都在你的可控范围内。
自定义Converter代码示例:

public class SomethingConverter : JsonConverter<ISomething>
{
    public override void WriteJson(JsonWriter writer, ISomething value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }

    public override ISomething ReadJson(JsonReader reader, Type objectType, ISomething existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 直接指定你要用的具体实现类,比如SomethingImpl
        return serializer.Deserialize<SomethingImpl>(reader);
    }
}

使用方式有两种:

  • 给属性添加JsonConverter特性:
public class Foo
{ 
    public int Number { get; set; }

    [JsonConverter(typeof(SomethingConverter))]
    public ISomething Thing { get; set; }
} 
  • 全局注册Converter到JsonSerializerSettings.Converters集合中,适合项目中所有用到ISomething的场景。

方案2:多实现场景用自定义类型标识+白名单控制

如果ISomething有多个不同的实现类需要区分,不要使用.NET自带的类型名作为标识,自己定义业务层面的类型标识,在Converter中只允许白名单内的类型被实例化,完全避免恶意类型注入风险。
Converter代码示例:

public class MultiSomethingConverter : JsonConverter<ISomething>
{
    public override ISomething ReadJson(JsonReader reader, Type objectType, ISomething existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jsonObj = JObject.Load(reader);
        // 读取自定义的类型标识字段
        var customType = jsonObj["CustomType"].Value<string>();
        
        ISomething instance = customType switch
        {
            "ImplA" => new SomethingImplA(),
            "ImplB" => new SomethingImplB(),
            _ => throw new NotSupportedException($"不支持的类型{customType}")
        };
        
        // 把JSON内容填充到实例中
        serializer.Populate(jsonObj.CreateReader(), instance);
        return instance;
    }

    public override void WriteJson(JsonWriter writer, ISomething value, JsonSerializer serializer)
    {
        var jsonObj = JObject.FromObject(value, serializer);
        // 序列化时写入自定义的类型标识
        jsonObj.AddFirst(new JProperty("CustomType", value.GetType().Name));
        jsonObj.WriteTo(writer);
    }
}

该方案允许反序列化的类型都是你在代码中明确指定的白名单类型,外部输入无法触发任意类型的实例化,没有TypeNameHandling带来的安全风险。

内容的提问来源于stack exchange,提问作者Al Pa chino

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:54:03