如何通过反射避免访问类的私有成员?

3
我正在阅读反射的安全考虑,看到了以下内容:

即使代码完全受信任,透明代码也不能使用反射访问安全关键成员。会抛出 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的作用,还是做错了什么?
1个回答

4
下面的要点指出:
- 使用部分信任运行的代码被视为透明。 - 从命令行运行的应用程序代码具有完全信任。只要它没有标记为透明,它就可以使用反射访问安全关键成员。当相同的代码使用部分信任运行(例如在沙箱应用程序域中),程序集的信任级别决定它是否可以访问安全关键代码:如果程序集具有强名称并且已安装在全局程序集缓存中,则是受信任的程序集并且可以调用安全关键成员。如果不受信任,则即使未标记为透明,也会变成透明,并且无法访问安全关键成员。
因此,要回答您标题中的问题:
“如何避免使用反射访问类的私有成员?”
如果无法将执行反射的代码隔离,则无法避免。

你说得对。但我希望我们能够这样做,反射很酷,在大多数情况下非常有用,但它也打破了语言的所有规则。 - Selman Genç
1
你必须认识到,任何由电脑运行的东西都可能会在某个时刻被其他进程检查到。如果您想隐藏实现细节,请了解混淆等技术。虽然这通常不值得花费精力。如果您真的有一些独特的算法,您绝对不希望任何人看到,那么请在您控制的服务器上运行它,并让用户发送参数。 - CodeCaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接