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?
So my personal answer, would be: reflection is a security risk, but not that big in practice if compared to other potential attack vectors.
There are many ways to prevent Singleton pattern from Reflection API, but one of the best solutions is to throw a run-time exception in the constructor if the instance already exists. In this, we can not able to create a second instance.
In my code, how can I prevent an immutable class being changed with reflection? Look into SecurityManager . Unless you are letting unknown people add plugins to something that you're creating, you shouldn't need to worry about this.
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
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!");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With