9

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

for(Field f : System.class.getDeclaredFields())
    System.out.println(f);

输出

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

有趣的是:该字段声明为

private static volatile SecurityManager security = null;

不在列表中,果然来电

System.class.getDeclaredField("security"); 

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

4

2 回答 2

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[]>();
}

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

Reflection.filterFields(this, getDeclaredFields0(publicOnly));

其中 filterFields 实现为

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

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

于 2013-07-23T08:54:48.207 回答
-1

首先,防止反射的方式可能是ifJVM 在字段获取机制下的一个脏:

if (strcmp(field, "security") == 0 && strcmp(class, "java.lang.System")) {
    return NULL;

(我并不是要暗示这是 JVM 中的实际代码!!)

这显然是大多数 java 用户无法访问的,因此唯一的其他选择是安装一个不允许私有字段和方法访问的安全管理器。这是可能的,但我不确定如何。

于 2013-07-22T20:35:10.920 回答