gpt4 book ai didi

c# - 是否可以将 Json.Net 设置为忽略 $type?

转载 作者:太空狗 更新时间:2023-10-29 21:11:51 25 4
gpt4 key购买 nike

正在观看 this video on json deserialization attacks它显示了这段 json,可用于在反序列化它的任何应用程序上触发任意代码执行。

Using ObjectDataProvider to execute arbitrary code

现在在我的应用程序中,我什至从不使用类型化的 json。我总是反序列化为动态对象或 JObject。我什至不知道 $type 属性,直到今天早上进行了另一次不相关的对话。

在我的 json 设置中有没有办法告诉它永远不要写入或读取这个属性?这不是我想要的。

最佳答案

"$type"信息仅在 TypeNameHandling 时写入被修改为 TypeNameHandling.None 以外的内容-- 这是默认值。如果您从不更改该值,"$type"永远不会发出信息。

同样"$type"TypeNameHandling = TypeNameHandling.None 时,属性在反序列化时被忽略(这也是默认值),如 docs 中所述:

// for security TypeNameHandling is required when deserializing
Stockholder newStockholder =
JsonConvert.DeserializeObject<Stockholder>(jsonTypeNameAuto, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});

如果您的代码(或您的代码使用的类库)中没有任何内容修改过 TypeNameHandlingTypeNameHandling.None以外的东西(通过 settings JsonPropertyAttribute.TypeNameHandling 等属性)那么代码执行攻击就无法工作。 (有关易受和不易受此攻击的 Json.NET 序列化器用法的更精确详细信息,请参阅 Alvaro Muñoz & Oleksandr Mirosh's blackhat paper

另请注意,如果您使用 JToken.Parse() 进行解析(或一些类似的静态方法,如 JObject.Parse() )而不是用 JsonSerializer.Deserialize<T>() 反序列化然后存在 "$type" properties 只会导致这些属性被填充到 JToken 中层次结构,因为 JToken.Parse()从不调用序列化程序。如果你仍然想剥离那些 "$type"解析后的属性,可以使用JsonExtensions.RemoveTypeMetadata(this JToken root)来自 Deserialize string that was serialized with TypeNameHandling.All 就是为了做到这一点。

也就是说,如果一个集合被另一个应用程序使用TypeNameHandling.Arrays序列化了。或 TypeNameHandling.All那么 JSON 中将有一个额外的嵌套级别。要在反序列化时剥离它,请参阅 IgnoreCollectionTypeConverter来自 Strategies for migrating serialized Json.NET document between versions/formats IgnoreArrayTypeConverter来自 Make Json.NET ignore $type if it's incompatible .

最后,如果您正在使用设置 TypeNameHandling 的第 3 方库在属性中,您可以使用自定义契约(Contract)解析器禁用它,如 How to disable TypeNameHandling when specified in attributes by using JsonSerializerSettings in Json.NET? 中所示.

如果您真的担心您团队中的其他人可能会启用 TypeNameHandling ,您可以创建自定义 ISerializationBinder 每当尝试解析类型或类型名称时都会抛出异常:

public class DisallowSerializationBindingBinder : ISerializationBinder
{
#region ISerializationBinder Members

public void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
throw new JsonSerializationException("Binding of subtypes has been disabled");
}

public Type BindToType(string assemblyName, string typeName)
{
throw new JsonSerializationException("Binding of subtypes has been disabled");
}

#endregion
}

然后在JsonSerializerSettings中设置如下:

var settings = new JsonSerializerSettings
{
SerializationBinder = new DisallowSerializationBindingBinder(),
};

并全局修改设置,如 Set default global json serializer settings所示(对于控制台应用程序), How to set custom JsonSerializerSettings for Json.NET in MVC 4 Web API? (对于 ASP.NET Web API)或 JsonSerializerSettings and Asp.Net Core (对于 asp.net 核心)。

关于c# - 是否可以将 Json.Net 设置为忽略 $type?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48159442/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com