当前位置: 首页 > 面试题库 >

由于Json.Net TypeNameHandling auto,外部json容易受到攻击吗?

白萧迟
2023-03-14
问题内容

我正在运营一个小型网站,用户可以在其中上传JSON中定义的自定义“对象”。最近,我了解了使用JSON自动类型反序列化的可能威胁:JSON
problem
。我认为我了解问题所在,但我必须要求确定。如果我仅使用给定的特定类型(此处为MyObject)反序列化传入的JSON,JsonConvert.DeserializeObject<MyObject>(json, settings);并且内部MyObject没有类型,MyObject并且该类型的任何成员的子类型都没有该类型,System.Object或者dynamic没有什么会变坏的,对吗?

TypeNameHandlingsettings设置为TypeNameHandling.Auto(我们不要质疑这个决定,它可能可以与工作None,但我想了解的问题将其设置为Auto。)

编辑:更多信息:我已经从前面提到的网站测试了JSON:

{
    "obj": {
        "$type": "System.IO.FileInfo, System.IO.FileSystem",
        "fileName": "rce-test.txt",
        "IsReadOnly": true
    }
}

如果MyObject有一个System.Objectdynamic键入的字段,obj我可以重现威胁。但是我想知道的是:即使MyObject是一个非常复杂的对象(包含很多(派生的)子对象,但它们都不是或具有System.Object或动态字段(即使不是类似的东西List<Object>?例如,我可以想象,$type即使找不到相关字段,Json.NET
也会根据信息执行类似创建对象的操作MyObject


问题答案:

TL / DR :在没有任何明显的objectdynamic成员,则 很可能 是安全的,但你不能 保证
是安全的。为了进一步降低风险,您应该遵循Newtonsoft文档中的建议:

当您的应用程序从外部源反序列化JSON时,应谨慎使用TypeNameHandling。反序列化除None以外的其他值时,应使用自定义SerializationBinder验证传入的类型。

完整答案

在Newtonsoft Json
和AlvaroMuñoz&Oleksandr Mirosh的blackhat
论文中, 如何配置Json.NET来创建易受攻击的Web
API

TypeNameHandling警告中
描述的攻击都取决于使用Json.NET
的设置来诱骗接收者构造
攻击小工具 -一种实例,在构造,填充或放置时会对接收系统造成攻击。
TypeNameHandling

Json.NET做两件事可以帮助防止此类攻击。首先,它忽略未知属性。因此,只需向其值包含一个"$type"属性的JSON有效负载中添加一个额外的未知属性就不会造成任何危害。其次,在多态值的反序列化期间,在解析"$type"属性时,它将检查解析的类型是否与预期的类型兼容JsonSerializerInternalReader.ResolveTypeName()

    if (objectType != null
#if HAVE_DYNAMIC
        && objectType != typeof(IDynamicMetaObjectProvider)
#endif
        && !objectType.IsAssignableFrom(specifiedType))
    {
        throw JsonSerializationException.Create(reader, "Type specified

in JSON ‘{0}’ is not compatible with
‘{1}’.”.FormatWith(CultureInfo.InvariantCulture,
specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
}

如果多态值的预期类型与任何攻击小工具类型都不兼容,则攻击将失败。只要你有型的无序列化的成员objectdynamic或者IDynamicMetaObjectProvider,这很可能是真的。但不确定!

即使数据模型中没有任何明显的非类型化成员,也可能构成攻击小工具的情况包括:

  • 未类型化 集合的 反序列化。如果你是反序列化任何类型的非类型化的集合或字典,如ArrayListList<object>Dictionary<string, dynamic>HashTable,那么你的系统很容易受到攻击包含在收集的物品的小工具。

  • 对从继承的数十个集合中的任何一个进行反序列化CollectionBase。此类型早于.Net引入泛型之前,它表示“半类型”集合,其中,项的类型在添加时会在运行时进行验证。由于验证是在构造之后进行的,因此存在一个可能会构造攻击小工具的窗口。

示例小提琴就显示了这一点。

  • 对与攻击工具(不仅仅是)共享通用基本类型或接口的值进行反序列化objectTempFileCollection实施ICollectionIDisposableObjectDataProvider实施INotifyPropertyChangedISupportInitialize。如果您有任何声明为这些接口中任何一个的多态成员或值,则很容易受到攻击。

  • 实现的类型的反序列化ISerializable。Json.NET 默认情况下支持此接口,并且某些外部库中看似无害的类型可能会在您不知情的情况下反序列化其流构造函数中的未类型化成员。

一个明显的例子是Sytem.Exception(或其任何子类型),它"Data"在其流构造函数中反序列化未类型字典,该流构造函数对应于未类型字典Exception.Data。如果要反序列化Exception(例如,很常见的包含在日志文件中),则以下JSON应该会造成攻击:

    {
  "$type": "System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
  "ClassName": "System.Exception",
  "Message": "naughty exception",
  "Data": {
    "$type": "System.Collections.ListDictionaryInternal, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
    "data": {
      "$type": "System.IO.FileInfo, System.IO.FileSystem",
      "fileName": "rce-test.txt",
      "IsReadOnly": true    
    }
  },
}

true`](https://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Serialization_DefaultContractResolver_IgnoreSerializableInterface.htm)。当然,这可能会导致某些.Net类库类型的序列化问题。

  • [Serializable]如果设置,则反序列化标记为的类型可能会有类似的问题DefaultContractResolver.IgnoreSerializableAttribute = false。但是,默认值为true,因此,如果不更改此设置,则应该确定。

  • 使用您 认为 未序列化的成员反序列化类型-如果存在则将反序列化。例如考虑以下类型:

    public MyType
    

    {
    public object tempData;
    public bool ShouldSerializeTempData() { return false; }
    }

借助Json.NET的条件序列化功能,该tempData成员将永远不会被序列化,因此您可能会觉得很清楚。但是,如果存在它将被
反序列化 !攻击者对您的代码进行反编译,并注意到这样的成员将能够为构建攻击小工具有效载荷MyType

这就是我能够想到的。如您所见,验证在大型对象图中从未尝试反序列化与某些攻击小工具兼容的多态类型是很重要的。因此,我强烈建议对自定义项进行附加保护,以SerializationBinder确保不会反序列化任何意外类型。



 类似资料:
  • 我正在构建一个专门使用JSON作为请求和响应内容的网络服务(即,没有表单编码的有效载荷)。 如果以下情况属实,web服务是否容易受到CSRF攻击? > 任何没有顶级JSON对象的POST请求,例如,,将被400拒绝。例如,内容为的请求将因此被拒绝。 任何具有以外的内容类型的请求将被400拒绝。例如,具有内容类型的请求将因此被拒绝。 所有GET请求都是安全的,因此不会修改任何服务器端数据。 客户端通

  • 我有这样一个类,它扩展了一个实现CustomTaskChange的类。由于一些类属性(如列名和类型)是通过XML文件传递给它的,所以我需要进行字符串级联。我确实使用PreparedStatement,但我想知道我是否仍然因为它而容易受到SQL注入的攻击,如果是这样的话,我该如何使它安全呢?XML是一个Liquibase变更集(我将在下面留下一个示例)。

  • 我的Java应用程序使用kerberos对Windows Active Directory KDC进行身份验证,它使用RC4-HMAC进行krb5配置文件中的、、。 通过将RC4-HMAC替换为es128-cts-hmac-sha1-96,应用程序给出了以下状态代码14的KrbException。 消息:KDC不支持加密类型javax.security.auth.login。FailedLogin

  • 问题内容: 我知道在调用时使用插值字符串是不安全的。 例如: 应该改写为: 调用时使用插值字符串是否安全?如果不是,应如何改写以下内容? 问题答案: 是的,ActiveRecord的是鈥涣刻申鈥方法 是 容易受到SQL注入。 不,这 不是 安全打电话时使用插值的字符串。 上述问题的答案已经由亚伦·帕特森(Aaron Patterson) 确认,他将我指向http://rails- sqli.org

  • 上下文:我们使用2.6.3版本的com.microsoft.azure:应用见解-日志-log4j1_2来检测我们的Scala代码。不幸的是,这依赖于1.2.17版本的log4j: log4j。1.2.17版本的log4j: log4j有一个严重的安全漏洞(参考:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17571)问题是:“L

  • 问题内容: 使用XStream(1.4.10)时,我始终收到红色的控制台错误 我尝试了以下方法: 和 没有一个能摆脱它。 我不需要任何高级的安全设置,我只是想使该警告静音。也许还准备1.5.x的代码 问题答案: 在处理安全问题时,我不会掉以轻心。首先,一个人要了解问题的严重性,这里写得很好,或者另一本书。 然后找出人们如何推荐该解决方案。最好的起点是xstream网站本身。您可以在xstream安