在 Intranet 区域、.Net 中实例化类时的安全问题
我有一个嵌入 HTML 页面(在 IE7 中)的 .Net 2.0 activex 控件。 我使用javascript来修改其属性和调用方法。在我调用使用 Activator.CreateInstance(type) 实例化类的方法之前,这一切都很好。我收到以下消息:
System.Reflection.TargetInitationException:调用目标已引发异常。 ---> System.Security.SecurityException:请求失败。
..
..
失败的操作是:InheritanceDemand
第一个失败的权限类型是:System.Security.PermissionSet
失败的程序集的区域是:Intranet
我试图实例化的类有一个无参数 public 构造函数,从我读到的内容来看,使用类型反射应该没有问题无论如何都是公开的?
我已使用 Microsoft .NET Framework 配置实用程序进行了临时修复,将 Intranet 信任修改为完全。请参阅此处。
如何修改方法、类或程序集以避免配置框架?
几点额外说明:
- activex 控件已编译 针对 .Net 2
- 它的程序集名称不强,
- 我不关心授予反射权限。
谢谢
更新
事实证明,导致问题的不是反射,而是对 TypeDescriptor.GetAttributes 的调用引发了 FileIOPermission 安全异常。我已使用以下代码修复了此问题:
Dim temp As New Security.Permissions.FileIOPermission(Security.Permissions.PermissionState.Unrestricted)
temp.Assert()
// Get attributes
System.Security.CodeAccessPermission.RevertAssert()
现在,如果我设置一个分配给程序集强名称的代码组并将权限集设置为 FullTrust,一切都很好。
但是,我似乎无法对其进行微调,它要么是 FullTrust,要么抛出异常(见下文)。即使是 Everything 权限集也不起作用。
例外:
System.Security.SecurityException: Request failed.
at System.Reflection.CustomAttribute._CreateCaObject(Void* pModule, Void* pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
at System.Reflection.CustomAttribute.CreateCaObject(Module module, RuntimeMethodHandle ctor, IntPtr& blob, IntPtr blobEnd, Int32& namedArgs)
at System.Reflection.CustomAttribute.GetCustomAttributes(Module decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
at System.RuntimeType.GetCustomAttributes(Type attributeType, Boolean inherit)
at System.ComponentModel.ReflectTypeDescriptionProvider.ReflectGetAttributes(Type type)
at System.ComponentModel.ReflectTypeDescriptionProvider.ReflectedTypeData.GetAttributes()
at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.DefaultTypeDescriptor.System.ComponentModel.ICustomTypeDescriptor.GetAttributes()
at System.ComponentModel.TypeDescriptor.GetAttributes(Object component, Boolean noCustomTypeDesc)
at System.ComponentModel.TypeDescriptor.GetAttributes(Object component)
... GetAttributes
...
The action that failed was: InheritanceDemand
The type of the first permission that failed was: System.Security.PermissionSet
The Zone of the assembly that failed was: Intranet
I have a .Net 2.0 activex control that is embedded within an HTML page (in IE7).
I use javascript to modify its properties and call methods. All this is fine until I call a method that instantiates a class using Activator.CreateInstance(type). I receive the following message:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Security.SecurityException: Request failed.
..
..
The action that failed was: InheritanceDemand
The type of the first permission that failed was: System.Security.PermissionSet
The Zone of the assembly that failed was: Intranet
The class I'm trying to instantiate has a parm-less public constructor, and from what I've read, there should be no problem using reflection on types that are public anyway?
I've done a temporary fix by using the Microsoft .NET Framework Configuration utility, to modify the intranet trust to full. See here.
How can I modify the method, class, or the assembly to avoid having to configure the framework?
A few extra points:
- The activex control is compiled
against .Net 2 - Its assembly is not strong named
- I'm not bothered about granting reflection permissions.
Thanks
Update
It turns out it wasn't reflection that was causing the problem, it was a call to TypeDescriptor.GetAttributes which threw a FileIOPermission security exception. I've fixed this with the following code:
Dim temp As New Security.Permissions.FileIOPermission(Security.Permissions.PermissionState.Unrestricted)
temp.Assert()
// Get attributes
System.Security.CodeAccessPermission.RevertAssert()
Now, If I set up a code group assigned to the strong name of my assembly and set the permission set to FullTrust, everything is fine.
However, I can't seem to fine-tune it, it's either FullTrust or an exception is thrown (see below). Even the Everything permission set doesn't work.
Exception:
System.Security.SecurityException: Request failed.
at System.Reflection.CustomAttribute._CreateCaObject(Void* pModule, Void* pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
at System.Reflection.CustomAttribute.CreateCaObject(Module module, RuntimeMethodHandle ctor, IntPtr& blob, IntPtr blobEnd, Int32& namedArgs)
at System.Reflection.CustomAttribute.GetCustomAttributes(Module decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
at System.RuntimeType.GetCustomAttributes(Type attributeType, Boolean inherit)
at System.ComponentModel.ReflectTypeDescriptionProvider.ReflectGetAttributes(Type type)
at System.ComponentModel.ReflectTypeDescriptionProvider.ReflectedTypeData.GetAttributes()
at System.ComponentModel.TypeDescriptor.TypeDescriptionNode.DefaultTypeDescriptor.System.ComponentModel.ICustomTypeDescriptor.GetAttributes()
at System.ComponentModel.TypeDescriptor.GetAttributes(Object component, Boolean noCustomTypeDesc)
at System.ComponentModel.TypeDescriptor.GetAttributes(Object component)
... GetAttributes
...
The action that failed was: InheritanceDemand
The type of the first permission that failed was: System.Security.PermissionSet
The Zone of the assembly that failed was: Intranet
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会将 ReflectionPermission 属性添加到您的 AssemblyInfo.cs 文件中,以便程序集尝试使用 RequireMinimum SecurityAction 反映到其他类中。
但是,请注意,这一切都会阻止您的应用程序在 Intranet 区域中运行,而不是运行一段时间,一切看起来都很好,直到反射发生。声明权限并不意味着它们会被授予,它只是允许程序“快速失败”。您可以随心所欲地请求许可; CAS 的全部基础是它不必授予您。
为了在应用程序或程序集中使用反射,您必须提供足够的证据以在限制较少的区域中运行程序集(例如,通过对其进行强签名),或者配置框架以将 ReflectionPermission 包含在 Intranet 权限集中。
最后,请注意,声明式 CAS 安全模型在 .NET Framework 4.0 中已基本弃用;如果您稍后尝试将此代码迁移到 .NET 4.0,则必须更改断言权限的方式。
I would add the ReflectionPermission attribute to your AssemblyInfo.cs file for the assembly attempting to reflect into the other class, with a RequireMinimum SecurityAction.
However, be aware that all this will do is prevent your application from running in the Intranet zone, instead of running for a while, all seems fine, till the reflection happens. Asserting permissions does not mean they'll be granted, it just allows a program to "fail fast". You can demand a permission all you want; the whole basis of CAS is that it doesn't have to be granted to you.
In order to use reflection in your app or assembly, you must either provide sufficient evidence to run the assembly in a less-restrictive zone (by strongly signing it, for instance), or configure the framework to include ReflectionPermission in the Intranet permission set.
Lastly, be aware that the declarative CAS security model is largely deprecated in .NET Framework 4.0; if you try to migrate this code to .NET 4.0 at a later date you will have to change the way you assert permissions.
如果类和构造函数都是公共的,那么通过反射调用构造函数应该不会有问题。然而,非公共类上的公共构造函数仍然会带来问题。
也就是说,鉴于这是一个失败的继承要求,听起来实际的问题可能出在其他地方。如果您尝试从控制代码创建该类的新实例而不使用反射,会发生什么情况?
You shouldn't have a problem with invoking the constructor via reflection if both the class and the constructor are public. However, a public constructor on a non-public class would still pose a problem.
That said, given that it is an inheritance demand that failed, it sounds like the actual problem might lie elsewhere. What happens if you attempt to create a new instance of the class from your control code without using reflection?