保护字段免受反射 - System.security的奇怪情况 [英] Protecting fields from Reflection - The strange case of the System.security

查看:106
本文介绍了保护字段免受反射 - System.security的奇怪情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently looking into java security and came across a strange phenomenon. The SecurityManager in java is stored in the field "security" in java.lang.System. Interestingly, the field seems to be protected against reflective access, which does make sense, but as far as I know this field is the only one which is. So here is the example:

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

有趣的是:声明为

Interestingly: the field declared as

private static volatile SecurityManager security = null;

不在列表中,并确定可以拨打

is not in the list, and sure enough a call to

System.class.getDeclaredField("security"); 

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

yields a NoSuchFieldException. As I couldn't find anything about this online, and I am pretty sure this field used to be accessible via reflection (see also, for example, this blog post from 2010 which describes accessing this field) I was wondering a) was this implemented as a quick fix to prevent easily disabling the securitymanager via reflection and b) how this is implemented (or rather is there any chance of protecting other private fields from reflection as well).

推荐答案

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

A colleague pointed out that the answer is not in the jvm but in the jdk, more precisely in the class sun.reflect.Reflection. There you'll find a static initializer that does the following

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中的getDeclaredFields方法。类我们将发现使用对Reflection类的调用来过滤字段:

If we now look a bit closer at the getDeclaredFields method in java.lang.Class we'll find that the fields are filtered using a call to the Reflection class:

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

其中filterFields实现为

where filterFields is implemented as

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

所以......这解决了字段受保护的问题。然而,我仍然很好奇为什么要这样做。

So .. this solves the issue how the field is protected. I am however still curious as to why this was implemented.

这篇关于保护字段免受反射 - System.security的奇怪情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆