使用不受信任的类型名称调用Type.GetType是否安全? [英] Is it safe to call Type.GetType with an untrusted type name?

查看:36
本文介绍了使用不受信任的类型名称调用Type.GetType是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I came across the following in a code review:

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

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

typeName originates from an AJAX request and is not validated. Does this pose any potential security issues? For example, is it possible for unexpected code to be executed, or for the entire application to crash (denial of service), as the result of loading arbitrary types from arbitrary assemblies?

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

(I suppose some joker could attempt to exhaust available memory by loading every type from every assembly in the GAC. Anything worse?)

注意:

  • 这是在完全信任下运行的ASP.NET应用程序.
  • 生成的 type 仅用于 ,如上所示.没有尝试实例化类型.
  • This is an ASP.NET application running under Full Trust.
  • The resulting type is only used as shown above. No attempt is made to instantiate the type.

推荐答案

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

No, this is not safe at all. Type.GetType will load an assembly if it has not been loaded before:

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

GetType causes loading of the assembly specified in typeName.

那么加载程序集怎么了?正如Daniel指出的那样,除了使用额外的内存外,.NET程序集 可以在加载时执行代码,即使该功能未提供给C#和VB.NET等常规编译器也是如此.这些被称为模块初始化程序.

So what's wrong with loading an assembly? Aside from it using additional memory as Daniel points out, .NET assemblies can execute code when they load, even though this functionality is not exposed to normal compilers like C# and VB.NET. These are called module initializers.

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

The module’s initializer method is executed at, or sometime before, first access to any types, methods, or data defined in the module

事实上,您正在加载程序集并检查其类型足以使模块初始化程序运行.

Just the fact that you are loading an assembly and examining its types is enough to get the module initializer to run.

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

Someone with a cleverly written assembly (say by using ilasm and writing raw MSIL) can execute code just by getting the assembly loaded and you examining the types. That's why we have Assembly.ReflectionOnlyLoad, so we can safely load the assembly in a non-executable environment.

我对此做了更多的思考,并想到了更多的案例.

I did a little more thinking about this and thought of a few more cases.

请考虑将您的应用程序池设置为运行64位.现在,假设您的攻击者使用AJAX服务来尝试加载仅适用于x86体系结构的程序集.例如,在我的GAC中有一个名为Microsoft.SqlServer.Replication的文件,它仅是x86,没有AMD64对应部分.如果我要求您的服务加载该程序集,则会得到 BadImageFormatException .根据您在加载程序集时使用的保护条款,未处理的异常可能会完全带来关闭您的AppPool .

Consider that your Application Pool is set to run 64-bit. Now imagine that your attacker uses the AJAX service to attempt to load an assembly that is strictly for x86 architecture only. For example, there is one in my GAC called Microsoft.SqlServer.Replication that is x86 only, there is no AMD64 counter-part. If I ask your service to load that assembly, you'd get a BadImageFormatException. Depending on what guard clauses you have in place around loading the assembly, unhandled exceptions could completely bring down your AppPool.

这篇关于使用不受信任的类型名称调用Type.GetType是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆