我正在阅读关于反射的安全注意事项,我看到了以下一行:
所以,我写了一个测试程序:透明代码不能使用反射来访问安全关键成员,即使代码是完全可信的。抛出MethodAccessException、FieldAccessException或TypeAccessException。
类库:
namespace ClassLibrary
{
public class Foo
{
[SecurityCritical] private int X;
}
}
测试程序:
using ClassLibrary;
namespace ReflectionSecurityTest
{
class Program
{
static void Main(string[] args)
{
Foo f = new Foo();
var flags = BindingFlags.Instance | BindingFlags.NonPublic;
var field = f.GetType().GetField("X", flags);
field.SetValue(f,15);
Console.WriteLine(field.GetValue(f));
}
}
}
我希望看到一个异常,但我在控制台中看到15
。问题是为什么 ?是我误解了SecurityCritical
的作用还是我做错了什么?
下面的要点说明:
以部分信任运行的代码被视为透明的。
从命令行运行的应用程序代码以完全信任的方式运行。只要不被标记为透明,它就可以使用反射来访问安全关键成员。当以部分信任运行相同代码时(例如,在沙盒应用程序域中),程序集的信任级别决定它是否可以访问安全关键代码:如果程序集具有强名称并且安装在全局程序集缓存中,则它是受信任的程序集,并且可以调用安全关键成员。如果它不受信任,即使它没有被标记为透明,它也会变得透明,并且它不能访问安全关键成员。
那么回答题目中的问题:
如何避免使用反射访问类的私有成员?
你不能,如果你不能沙箱代码执行反射