繁体   English   中英

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

[英]Is it possible to set Json.Net to ignore $type?

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

使用ObjectDataProvider执行任意代码

现在在我的应用程序中,我甚至从未使用过类型的json。 我总是反序列化为动态对象或JObject 在今天早上另一个无关的对话之前,我甚至都不知道$type属性。

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

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

类似地,当TypeNameHandling = TypeNameHandling.None (同样是默认值)时,反序列化时会忽略"$type"属性,如文档中所述:

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

如果没有在你的代码(或在代码中使用类库)不断修改TypeNameHandling比其他东西TypeNameHandling.None (通过设置或属性, JsonPropertyAttribute.TypeNameHandling ),那么代码执行攻击不能工作。 (有关Json.NET的序列化程序的使用的更准确的细节,这些序列化程序不易受此攻击,请参阅AlvaroMuñoz和Oleksandr Mirosh的黑帽纸

另请注意,如果使用JToken.Parse() (或某些类似的静态方法,如JObject.Parse() )进行语法分析而不是使用JsonSerializer.Deserialize<T>()进行反序列化,那么"$type"属性的存在将只是因为JToken.Parse()从不调用序列化程序,导致这些属性被填充到JToken层次结构中。 如果你想在解析后JsonExtensions.RemoveTypeMetadata(this JToken root)那些"$type"属性,你可以使用来自用TypeNameHandling.All序列化的Deserialize字符串的 JsonExtensions.RemoveTypeMetadata(this JToken root)来做到这一点。

话虽这么说,如果一个集合是由另一个使用TypeNameHandling.ArraysTypeNameHandling.All应用程序序列化的,那么JSON中会有一个额外的嵌套级别。 要在反序列化时 IgnoreArrayTypeConverter它,请参阅Strategies中的 IgnoreCollectionTypeConverter以便在版本/格式之间迁移序列化的Json.NET文档,或者从Make Json.NET中忽略 IgnoreArrayTypeConverter如果它不兼容,则忽略$ type

最后,如果您正在使用在属性中设置TypeNameHandling第三方库,则可以使用自定义合约解析程序禁用它,如在JSON.NET中使用JsonSerializerSettings在属性中指定的如何禁用TypeNameHandling中所示

如果您真的担心团队中的其他人可能启用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(),
};

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

不幸的是, TypeNameHandling.None被忽略。 但你可以使用:

public static JsonSerializerSettings JsonSerializationSettings
        = new JsonSerializerSettings
{
    MetadataPropertyHandling = MetadataPropertyHandling.Ignore
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM