是否可以将Json.Net设置为忽略$ type?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以将Json.Net设置为忽略$ type?相关的知识,希望对你有一定的参考价值。
观察this video on json deserialization attacks并显示这一点json,可用于在任何反序列化它的应用程序上触发任意代码执行。
现在在我的应用程序中,我甚至从未使用过类型的json。我总是反序列化为动态对象或JObject
s。我甚至不知道$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
});
如果您的代码(或代码使用的类库)中的任何内容都没有将TypeNameHandling
修改为TypeNameHandling.None
以外的其他内容(通过settings或JsonPropertyAttribute.TypeNameHandling
等属性),则代码执行攻击无法正常工作。 (有关Json.NET的序列化程序使用的更准确的详细信息,请参阅Alvaro Muñoz & Oleksandr Mirosh's blackhat paper。
另请注意,如果使用JToken.Parse()
(或某些类似的静态方法,如JObject.Parse()
)进行语法分析而不是使用JsonSerializer.Deserialize<T>()
进行反序列化,那么"$type"
属性的存在将导致这些属性填充到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
的第三方库,则可以使用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核心)所示。
以上是关于是否可以将Json.Net设置为忽略$ type?的主要内容,如果未能解决你的问题,请参考以下文章
为啥当我使用 JSON.NET 反序列化时会忽略我的默认值?
是否可以在C ++中以编程方式查询不同的DNS名称服务器,忽略系统设置?