当前位置: 首页 > 面试题库 >

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

关苗宣
2023-03-14
问题内容

我目前正在研究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)如何实现此功能(或者也有可能保护其他私有字段免受反射)。


问题答案:

一位同事指出,答案不是在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));
}

因此..这解决了如何保护字段的问题。但是,我仍然对为什么要实施这一点感到好奇。



 类似资料:
  • 问题内容: 如何通过反射访问对象的继承保护字段? 问题答案: 您可能会遇到两个问题-字段可能无法正常访问(私有),并且不在您正在查看的类中,而是位于层次结构中的某个位置。 这样的事情甚至可以解决这些问题:

  • 问题内容: 我有一个json字符串im可以通过简单的eval(string)转换为对象; 我正在尝试像这样访问它 我的问题是javascript不喜欢字段名中的#。是否可以访问它? 问题答案:

  • 问题内容: 如果我在SQL Server Express 2008上运行此查询: 它将日期存储为2011年4月11日 我该如何预防呢? 问题答案: 使用ISO-8601格式:(或)-无论您使用哪种SQL Server语言和区域设置,它始终有效。 SQL Server中的日期 不 以任何特定的面向字符串的格式存储-日期即是日期即是日期,无论您看到什么。 您会看到日期的字符串表示形式-但又一次:日期

  • 这是发生在中的一种奇怪行为,下面是一个场景,一个名为Entity的类: 主要课程包括: 输出: 好的,它们是有序的,这很好,但是当您设置对某个

  • 我最近注意到一些流口水规则的奇怪行为。我有班级心率,它有以下字段: 我的规则文件如下: 我想将字段<代码>心率更改为<代码>心率,并在我的规则中更改字段名称,以便我的新规则现在是: 但这会产生错误,即drools无法解析该字段的心率。但是,当我将规则更改回原来的规则时,使用心率(heartRate),它可以正常工作,尽管这样的字段已经不存在了。我得到以下错误: