13

In Java docs it mentioned that using f.setAccessible(true) method we can violate the principal of encapsulation.

But if I am writing any class which has full security, for instance with a private variable, how can I prevent it from being accessed with reflection?

For example I have a class with full secured instance variable:

public final class Immutable {
    private final int someVal;

    public Immutable(int someVal) {
        this.someVal = someVal;
    }

    public int getVal() {
        return someVal;
    }
}

But I can modify that instance variable using reflection like this:

public class Tester {
    public static void main(String[] args)
            throws NoSuchFieldException, SecurityException,
            IllegalArgumentException, IllegalAccessException {

        Immutable i = new Immutable(10);

        // output 10
        System.out.println(i.getVal());

        Field f = i.getClass().getDeclaredField("someVal");
        f.setAccessible(true);
        f.set(i, 11);

        // output is 11 which implies some value modified
        System.out.println(i.getVal());
    }
}

In my code, how can I prevent an immutable class being changed with reflection?

Radiodef
  • 37,180
  • 14
  • 90
  • 125
Naz
  • 390
  • 1
  • 4
  • 15
  • 1
    Look into `SecurityManager`. – Sotirios Delimanolis Mar 25 '15 at 01:42
  • 2
    Unless you are letting unknown people add plugins to something that you're creating, you shouldn't need to worry about this. What application are you trying to make? – satnam Mar 25 '15 at 01:54
  • And if you are concerned about security restricting access to reflection isn't really enough on its own to be worthwhile. If the untrusted code can read, write or delete any file on the computer then it isn't much help to the owner of the computer that it can't access one object property. – bdsl Nov 14 '21 at 12:34

2 Answers2

10

The JVM has security mechanisms built into it that allow you to define restrictions to code through a Java security policy file. The Java security manager uses the Java security policy file to enforce a set of permissions granted to classes. The permissions allow specified classes running in that instance of the JVM to permit or not permit certain runtime operations. If you enable the Java security manager but do not specify a security policy file, the Java security manager uses the default security policies defined in the java.security and java.policy files in the $JAVA_HOME/jre/lib/security directory. Defining your policy file can be found here http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html

kk1992
  • 153
  • 1
  • 3
9

Extend the SecurityManager class and override this method to restrict reflection access

@Override
public void checkPackageAccess(String pkg){

         // don't allow the use of the reflection package
         if(pkg.equals("java.lang.reflect")){
             throw new SecurityException("Reflection is not allowed!");
         }
     }
Pankaj Jaiswal
  • 689
  • 8
  • 16
  • 1
    super.checkPackageAccess(pkg); is missing which is very important!!! – sampopes Oct 03 '20 at 06:17
  • I'm missing something. Firstly you don't say what to do with your extended SecurityManager. Secondly, what stops a client of your code doing whatever it was you're doing with that extended SecurityManager with their own? – barneypitt Sep 19 '22 at 11:06