是否可以将Json.Net设置为忽略$ type? [英] Is it possible to set Json.Net to ignore $type?

查看:101
本文介绍了是否可以将Json.Net设置为忽略$ type?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

观看有关JSON反序列化攻击的视频,它显示了json的这一点,可用于在反序列化任何应用程序上触发任意代码执行.

Watching this video on json deserialization attacks and it shows this bit of json that can be used to trigger arbitrary code execution on any application that deserializes it.

现在在我的应用程序中,我什至从未使用过键入的json.我总是反序列化为动态对象或JObject.直到今天早上又进行了一次无关的交谈,我才知道$type属性.

Now in my applications, I never even use typed json. I always deserialize to dynamic objects or JObjects. I didn't even know about the $type property until another unrelated conversation this morning.

我的json设置中是否有一种方法可以告诉它永不写入或读取此属性?这不是我想要的.

Is there a way in my json settings to tell it never to write nor read this property? It's not something I would ever want.

推荐答案

"$type"信息仅在 TypeNameHandling 修改为TypeNameHandling.None -这是默认设置.如果您从不更改该值,则不会发出"$type"信息.

"$type" information is only written when TypeNameHandling is modified to something other than TypeNameHandling.None -- which is the default. If you never change the value, "$type" information is never emitted.

同样,如如果您的代码(或您的代码使用的类库)中没有任何内容将TypeNameHandling修改为TypeNameHandling.None以外的其他内容(通过 JsonPropertyAttribute.TypeNameHandling ),则该代码执行攻击将无法进行. (有关不受此攻击影响的且不易受Json.NET序列化器使用的更精确的详细信息,请参见

If nothing in your code (or in class libraries used by your code) ever modifies TypeNameHandling to something other than TypeNameHandling.None (either via settings or attributes such as JsonPropertyAttribute.TypeNameHandling) then that code execution attack cannot work. (For more precise details on usages of Json.NET's serializer that are and are not vulnerable to this attack, see 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) TypeNameHandling.All 即可做到这一点.

Also note that, if you are parsing with JToken.Parse() (or some similar static method like JObject.Parse()) rather than deserializing with JsonSerializer.Deserialize<T>() then the presence of "$type" properties will simply result in such properties getting populated into the JToken hierarchy, since JToken.Parse() never invokes the serializer. If you nevertheless want to strip those"$type" properties after parsing, you can use JsonExtensions.RemoveTypeMetadata(this JToken root) from Deserialize string that was serialized with TypeNameHandling.All to do just that.

也就是说,如果 collection 由另一个应用程序使用TypeNameHandling.ArraysTypeNameHandling.All进行了序列化,则JSON中将有一个额外的嵌套层.要在反序列化时删除它,请参阅 在版本/格式之间迁移序列化Json.NET文档的策略. IgnoreArrayTypeConverter来自 如果不兼容,请让Json.NET忽略$ type

That being said, if a collection was serialized by another application using TypeNameHandling.Arrays or TypeNameHandling.All then there will be an extra level of nesting in the JSON. To strip it when deserializing, see IgnoreCollectionTypeConverter from Strategies for migrating serialized Json.NET document between versions/formats or IgnoreArrayTypeConverter from Make Json.NET ignore $type if it's incompatible.

最后,如果您正在使用在属性中设置TypeNameHandling的第三方库,则可以使用自定义合同解析器禁用该库,如

Finally, if you are working with a 3rd party library that sets TypeNameHandling in attributes, you can disable that with a custom contract resolver as shown in How to disable TypeNameHandling when specified in attributes by using JsonSerializerSettings in Json.NET?.

如果您真的担心团队中的其他人可能会启用TypeNameHandling,则可以创建自定义

And if you're really concerned that somebody else in your team might enable TypeNameHandling, you could create a custom ISerializationBinder that throws an exception whenever an attempt is made to resolve a type or type name:

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中进行如下设置:

Then set it in JsonSerializerSettings as follows:

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

并按照 设置默认的全局json序列化程序设置 (针对控制台应用程序), 如何在MVC 4 Web API中为Json.NET设置自定义JsonSerializerSettings? (对于ASP.NET Web API)或 JsonSerializerSettings和Asp.Net Core (对于ASP .net核心).

And modify the settings globally as shown in Set default global json serializer settings (for a console app), How to set custom JsonSerializerSettings for Json.NET in MVC 4 Web API? (for ASP.NET Web API) or JsonSerializerSettings and Asp.Net Core (for asp.net core).

这篇关于是否可以将Json.Net设置为忽略$ type?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆