调用Type是否安全?带有不受信任类型名称的GetType

本文关键字:类型 信任 GetType 是否 Type 安全 调用 | 更新日期: 2023-09-27 18:05:37

我在一次代码审查中遇到了以下问题:

Type type = Type.GetType(typeName);
if (type == typeof(SomeKnownType))
    DoSomething(...); // does not use type or typeName

typeName来自AJAX请求,未经过验证。这会造成任何潜在的安全问题吗?例如,是否可能执行意外的代码,或者执行整个应用程序崩溃(拒绝服务),从任意程序集加载任意类型的结果?

(我想有些人可能会试图通过从GAC中的每个程序集中加载每种类型来耗尽可用内存。更糟吗?)

指出:

  • 这是一个ASP。. NET应用程序在完全信任下运行
  • 生成的type,只有如上所示使用。没有尝试实例化类型。

调用Type是否安全?带有不受信任类型名称的GetType

不,这一点也不安全。类型。GetType将加载以前未加载过的程序集:

GetType导致加载typeName中指定的程序集。

那么加载程序集有什么问题呢?除了Daniel指出的使用额外内存之外,. net程序集可以在加载时执行代码,即使这个功能不暴露给像c#和VB.NET这样的普通编译器。这些被称为模块初始化式。

模块的初始化方法在第一次访问模块中定义的任何类型、方法或数据时或之前执行

只要加载程序集并检查其类型,就足以使模块初始化器运行。

拥有一个巧妙编写的程序集(比如使用ilasm和编写原始MSIL)的人可以通过加载程序集并检查类型来执行代码。这就是为什么我们有大会。

在非可执行环境中安全地加载程序集。

我多想了一下,想到了更多的例子。

假设您的应用程序池被设置为运行64位。现在假设攻击者使用AJAX服务试图加载一个严格只适用于x86架构的程序集。例如,在我的GAC中有一个名为Microsoft.SqlServer.Replication的,它仅支持x86,没有AMD64对应部分。如果我要求你的服务来加载组件,你会得到一个BadImageFormatException。根据加载程序集时使用的保护子句的不同,未处理的异常可能会完全破坏AppPool。

如果库不在内存中,它可能会占用内存。

我将Dictionary<string, Type>作为允许的列表。

var whitelist = new Dictionary<string, Type>;
whitelist.Add("MyType", typeof(MyType));

引用类型本身没有继承危险。. net中的信任位于程序集级别。如果没有包含指定类型的可用程序集,则调用将只返回null。因此,必须有人为代码提供程序集——程序集不是凭空出现的。