保护字段免受反射 - System.security的奇怪情况

Arn*_*ach 8 java security reflection

我目前正在研究java安全性并遇到了一个奇怪的现象.java中的SecurityManager存储在java.lang.System中的"security"字段中.有趣的是,该领域似乎受到反射访问的保护,这确实有意义,但据我所知,这个领域是唯一的.所以这是一个例子:

for(Field f : System.class.getDeclaredFields())
    System.out.println(f);
Run Code Online (Sandbox Code Playgroud)

输出

public static final java.io.InputStream java.lang.System.in
public static final java.io.PrintStream java.lang.System.out
public static final java.io.PrintStream java.lang.System.err
private static volatile java.io.Console java.lang.System.cons
private static java.util.Properties java.lang.System.props
private static java.lang.String java.lang.System.lineSeparator
Run Code Online (Sandbox Code Playgroud)

有趣的是:该领域被宣布为

private static volatile SecurityManager security = null;
Run Code Online (Sandbox Code Playgroud)

不在列表中,肯定是打电话给

System.class.getDeclaredField("security"); 
Run Code Online (Sandbox Code Playgroud)

产生NoSuchFieldException.因为我在网上找不到任何关于这个的信息,我很确定这个字段曾经可以通过反思访问(例如,参见2010年的博客文章,描述访问该字段)我想知道a)是否已实现作为快速修复,以防止通过反射轻松禁用安全管理器和b)如何实现(或者更确切地说,有任何机会保护其他私有字段免受反射).

Arn*_*ach 5

一位同事指出,答案不在jvm中,而在jdk中,更准确地说是在类sun.reflect.Reflection中。在那里你会找到一个静态初始化器,它执行以下操作

static {
    Map<Class,String[]> map = new HashMap<Class,String[]>();
    map.put(Reflection.class,
        new String[] {"fieldFilterMap", "methodFilterMap"});
    map.put(System.class, new String[] {"security"});
    fieldFilterMap = map;

    methodFilterMap = new HashMap<Class,String[]>();
}
Run Code Online (Sandbox Code Playgroud)

如果我们现在仔细查看 java.lang.Class 中的 getDeclaredFields 方法,我们会发现这些字段是通过调用 Reflection 类来过滤的:

Reflection.filterFields(this, getDeclaredFields0(publicOnly));
Run Code Online (Sandbox Code Playgroud)

其中 filterFields 实现为

public static Field[] filterFields(Class containingClass,
                                   Field[] fields) {
    if (fieldFilterMap == null) {
        // Bootstrapping
        return fields;
    }
    return (Field[])filter(fields, fieldFilterMap.get(containingClass));
}
Run Code Online (Sandbox Code Playgroud)

所以..这解决了如何保护该领域的问题。然而,我仍然很好奇为什么要实施这一点。