How to restrict developers to use reflection to access private methods and constructors in Java?
How to restrict developers to use reflection to access private methods and constructors in Java?
Using normal Java code we can't access private constructors or private methods outside of a class. But by using reflection we can access any private methods and constructors in a Java class.
So how can we give security to our Java code?
Run your application using a SecurityManager
and a sufficiently restrictive security policy.
There's a short summary in the tutorial and extensive information in the security documentation.
Add checkPermission()
method in all of your private method/constructor.
checkPermission using sun.reflect.Reflection.getCallerClass(int n)
by assert callerClass=selfClass
.
The getCallerClass
returns the class of the method realFramesToSkip
frames up the stack (zero-based), ignoring frames associated with java.lang.reflect.Method.invoke()
and its implementation. The first frame is that associated with this method, so getCallerClass(0)
returns the Class object for sun.reflect.Reflection
.
public class PrivateConstructorClass {
private PrivateConstructorClass() {
checkPerMission();
//you own code go below
}
void checkPerMission() {
Class self = sun.reflect.Reflection.getCallerClass(1);
Class caller = sun.reflect.Reflection.getCallerClass(3);
if (self != caller) {
throw new java.lang.IllegalAccessError();
}
}
}
You can try to test reflect, it will fail:
public class TestPrivateMain {
Object newInstance() throws Exception {
final Class<?> c = Class.forName("package.TestPrivate");
final Constructor<?> constructor = c.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
}
public static void main(String[] args) throws Exception {
Object t = new TestPrivateMain().newInstance();
}
}
You (as the developer of the code in question) cannot do that.
The end user, who runs the application, could install a SecurityManager that forbids reflection.