Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 671
Satya Avatar asked Sep 27 '11 09:09

Satya


People also ask

Can reflection access private methods?

You can access the private methods of a class using java reflection package.

Can Java reflection API access private fields and methods of a class?

Despite the common belief it is actually possible to access private fields and methods of other classes via Java Reflection. It is not even that difficult. This can be very handy during unit testing.

How do I stop reflection in Java?

Yes, reflection is slow, and it creates fragile code when used in this way. If you want to avoid the if statement, you should use polymorphism.

Can constructor access private methods?

Private fields are accessible on the class constructor from inside the class declaration itself. They are used for declaration of field names as well as for accessing a field's value.


3 Answers

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.

like image 182
Joachim Sauer Avatar answered Oct 17 '22 20:10

Joachim Sauer


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();
    }
} 
like image 21
swanliu Avatar answered Oct 17 '22 21:10

swanliu


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.

like image 31
Thilo Avatar answered Oct 17 '22 20:10

Thilo