Is it safe to call Type.GetType with an untrusted type name?

元气小坏坏 提交于 2021-02-07 11:16:09

问题


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 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?

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

Notes:

  • 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.

回答1:


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

GetType causes loading of the assembly specified in typeName.

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.

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.

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.




回答2:


It could eat up memory potentially if the libraries aren't in memory.

I would have a Dictionary<string, Type> as an allowed list.

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



回答3:


There is no inherit danger in referring to the type itself. Trust in .NET is at the assembly level. If there's no available assembly that contains the specified type, your call will just return a null. Accordingly, somebody has to make the assembly available for the code -- assemblies don't just appear out of thin air.



来源:https://stackoverflow.com/questions/23895563/is-it-safe-to-call-type-gettype-with-an-untrusted-type-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!