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

问题描述 投票:6回答:1

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

Using ObjectDataProvider to execute arbitrary code

现在在我的应用程序中,我甚至从未使用过类型的json。我总是反序列化为动态对象或JObjects。我甚至不知道$type财产,直到今天早上另一个无关的谈话。

在我的json设置中是否有一种方法可以告诉它永远不会写或读取此属性?这不是我想要的东西。

c# json json.net
1个回答
8
投票

"$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以外的其他内容(通过settingsJsonPropertyAttribute.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.ArraysTypeNameHandling.All的应用程序序列化的,那么JSON中会有一个额外的嵌套级别。要在反序列化时去除它,请参阅IgnoreCollectionTypeConverterStrategies for migrating serialized Json.NET document between versions/formatsIgnoreArrayTypeConverterMake 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核心)所示。

© www.soinside.com 2019 - 2024. All rights reserved.