Protecting fields from Reflection is a strange case of System.security

I am currently studying Java security and have come across a strange phenomenon. The SecurityManager in java is stored in the "security" field in java.lang.System. Interestingly, the field seems to be protected from reflective access, which makes sense, but as far as I know, this field is the only one. So here is an example:

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

exits

 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 

Interesting: field declared as

 private static volatile SecurityManager security = null; 

missing from the list and of course the call

 System.class.getDeclaredField("security"); 

throws a NoSuchFieldException. Since I could not find anything about this on the Internet, and I am sure that this field was accessible through reflection (see also, for example, this blog post from 2010 that describes access to this field) I was interested, a) it was whether it is implemented as a quick solution to prevent a simple disabling of security control through reflection; and b) how it is implemented (or, rather, there is a chance to protect other private fields from reflection).

+8
java reflection security
source share
2 answers

A colleague noted that the answer is not in jvm, but in jdk, more precisely in the sun.reflect.Reflection class. There you will 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[]>(); } 

If we now look a little closer to the getDeclaredFields method in java.lang.Class, we find that the fields are filtered by calling the Reflection class:

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

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 problem of protecting the field. However, I am still interested to know why this was implemented.

+3
source share

First, the way this was prevented from reflection was probably dirty if in the JVM with the field getting mechanism:

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

(I do NOT mean that this is the actual code in the JVM !!)

This is obviously not available to most java users, so the only option is to install a security manager that denies access to the private field and method. It is possible, but I'm not sure how to do it.

-one
source share

All Articles