JDK-8255433 : Clarify missing access check for protected or public nested type in non-public enclosing class
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 8,11,17,21
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2020-10-25
  • Updated: 2025-04-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
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 ----------


Comments
This might be added to the "Java programming language and JVM modeling in core reflection" section of java.lang.reflect package specification, or on `Class.getModifiers` (which can return inner class modifiers( Note that `AccessibleObject` is not suitable, as this access still requires the field/methods to be already accessible when the class access is implicitly widened by the class files.
14-04-2025

A known behavior, see JDK-8308040 and related bugs.
27-06-2023

It is possible to access the members of a protected or public type which is inside a non-public enclosing class. However there is no explicit explanation of accessing public or protected nested fields in non-public classes anywhere in JLS or reflection javadocs. The behavior can be seen in the test code. Classes which are exposed to untrusted code this detail is important as any malicious code could mess with the implementation details.
27-10-2020