A DESCRIPTION OF THE PROBLEM :
It appears that using reflection it is possible to access the members of a protected or public type which is inside a non-public enclosing class.
JLS 15 §15.12.4.3 hints that a little bit, but it is neither written in the JLS section §6.6 nor in the `java.lang.reflect.AccessibleObject` documentation explicitly.
Especially for classes which is exposed to untrusted code this detail is important because otherwise malicious code could mess with implementation details.
(Might also be worth verifying that the JDK classes are not affected)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Save the code for `TopLevel1` provided below as `test1/TopLevel1.java`
2. Save the code for `TopLevel2` provided below as `test2/TopLevel2.java`
3. Compile both files
4. Run `TopLevel2`'s main method
ACTUAL -
`TopLevel2` can modify a field of a nested class within a non-public enclosing class, even with a SecurityManager in place.
---------- BEGIN SOURCE ----------
package test1;
// package-private
class TopLevel1 {
private static class Nested1_1 {
protected static class Nested1_2 {
public static int i;
}
}
}
---------------------------------------------
package test2;
import java.lang.reflect.Field;
public class TopLevel2 {
public static void main(String... args) throws Exception {
System.setSecurityManager(new SecurityManager());
Class<?> nested1_2 = Class.forName("test1.TopLevel1$Nested1_1$Nested1_2");
Field f = nested1_2.getDeclaredField("i");
f.set(null, 1);
}
}
---------- END SOURCE ----------