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

时间:2014-05-27 17:32:26

标签: c# asp.net .net security

我在代码审核中遇到了以下内容:

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

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

(我想有些小丑可能会尝试通过加载GAC中每个程序集的每种类型来耗尽可用内存。还有什么更糟糕的吗?)

注意:

  • 这是在完全信任下运行的ASP.NET应用程序。
  • 结果type ,如上所示。没有尝试实例化该类型。

3 个答案:

答案 0 :(得分:19)

不,这根本不安全。 Type.GetType如果之前尚未加载,则会加载程序集:

  

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

加载程序集有什么问题?除了使用额外的内存,Daniel指出,.NET程序集可以在加载时执行代码,即使这些功能没有暴露给像C#和VB.NET这样的普通编译器。这些被称为module initializers

  

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

您正在加载程序集并检查其类型,这足以让模块初始化程序运行。

有一个巧妙编写的程序集(比如通过使用ilasm和编写原始MSIL)可以通过加载程序集并检查类型来执行代码。这就是为什么我们有Assembly.ReflectionOnlyLoad,所以我们可以安全地在不可执行的环境中加载程序集。


我做了一些更多的思考,并考虑了几个案例。

请考虑将您的应用程序池设置为运行64位。现在假设您的攻击者使用AJAX服务尝试加载仅严格用于x86架构的程序集。例如,我的GAC中有一个名为Microsoft.SqlServer.Replication,仅为x86,没有AMD64对应部分。如果我要求您的服务加载该程序集,您将获得BadImageFormatException。根据您在加载程序集时所使用的保护条款,未处理的异常可能完全bring down your AppPool

答案 1 :(得分:4)

如果库不在内存中,它可能会耗尽内存。

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

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

答案 2 :(得分:0)

引用类型本身没有继承危险。 .NET中的信任处于程序集级别。如果没有包含指定类型的可用程序集,则您的调用将返回null。因此,有人必须使组件可用于代码 - 组件不会出现在空气中。