首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >保护字段不受反射-- System.security的奇怪情况

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

Stack Overflow用户
提问于 2013-07-23 04:30:25
回答 2查看 1.4K关注 0票数 9

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

代码语言:javascript
复制
for(Field f : System.class.getDeclaredFields())
    System.out.println(f);

输出

代码语言:javascript
复制
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

有趣的是:字段声明为

代码语言:javascript
复制
private static volatile SecurityManager security = null;

不在列表中,并且肯定会调用

代码语言:javascript
复制
System.class.getDeclaredField("security"); 

生成NoSuchFieldException。因为我在网上找不到任何关于这个的东西,而且我非常确定这个字段过去是可以通过反射访问的(例如,参见2010年的这个描述访问这个字段的blog post ),我想知道a)这是不是作为一个快速修复来实现的,以防止通过反射轻松禁用securitymanager;b)这是如何实现的(或者更确切地说,有没有可能保护其他私有字段不受反射的影响)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-23 16:54:48

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

代码语言:javascript
复制
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方法,我们会发现字段是使用对反射类的调用进行过滤的:

代码语言:javascript
复制
Reflection.filterFields(this, getDeclaredFields0(publicOnly));

其中filterFields实现为

代码语言:javascript
复制
public static Field[] filterFields(Class containingClass,
                                   Field[] fields) {
    if (fieldFilterMap == null) {
        // Bootstrapping
        return fields;
    }
    return (Field[])filter(fields, fieldFilterMap.get(containingClass));
}

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

票数 5
EN

Stack Overflow用户

发布于 2013-07-23 04:35:11

首先,防止反射的方法可能是在字段获取机制下的JVM中的一个脏if

代码语言:javascript
复制
if (strcmp(field, "security") == 0 && strcmp(class, "java.lang.System")) {
    return NULL;

(我并不是说这就是JVM中的实际代码!)

这显然对大多数java用户是不可访问的,所以唯一的其他选择是安装一个安全管理器,它禁止私有字段和方法访问。这是可能的,但我不确定是怎么做的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17796815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档