Java Security Manager completely disable reflection
Asked Answered
K

3

13

I've been reading quite a lot of questions on Stackoverflow about this question but couldn't quit find a solution or answer for my problem. If there is already one I would be grateful if somebody would give a hint ...

My problem/question is if it is possible to completely disable reflection for not trustworthy code? Functions like getDeclaredMethods()(See test.java). I've already got a Java Security Manager which throws Security Exceptions if the code tries to write/read/etc. ...

If it is possible, can somebody show me how?

Bruno

test.java

TestClass cls = new TestClass();
Class c = cls.getClass();

// returns the array of Method objects 
Method[] m = c.getDeclaredMethods();
for(int i = 0; i < m.length; i++) {
   System.out.println("method = " + m[i].toString());
}
Kolyma answered 24/10, 2016 at 12:53 Comment(0)
K
6

So I solved the problem not directly with checkPermission(). My workaround is to check if the java.lang.reflect package is accessed.

@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!");
    }
}
Kolyma answered 28/10, 2016 at 9:24 Comment(1)
I may be wrong here, but I'm quite sure if (pkg.startsWith("java.lang.reflect")){ would be way safer.Larsen
S
5

Extend your SecurityManager and have it check for ReflectPermission and RuntimePermission. Then you have to decide whether the caller has permission for Reflection:

@Override
public void checkPermission(Permission perm) {
  if (perm instanceof ReflectPermission) {
    // called for Method.setAccessible(true)
    // determine whether caller is permitted    using getClassContext()
  }
  if (perm instanceof RuntimePermission) {
    if (perm.implies(new RuntimePermission("accessDeclaredMembers"))) {
      // called for Class.getDeclardFields()
      System.out.println("getDeclaredFields() called");
    }
}
Shealy answered 24/10, 2016 at 13:42 Comment(5)
I copied your code and added a throw new SecurityException(...) but the exception isn't thrown... the function isn't even called ...Kolyma
Yes, it is not called for getDeclaredMethods(), but if you want to access private/protected methods via Method.setAccessible(true) the SecurityManager is called.Shealy
I updated the answear for a check for getDeclardXYZ(). Hope it helps.Shealy
It's not working aswell I don't know why but the checkPermission function isn't even called ...Kolyma
Is the policy global or can you set it to a specific package? For instance, in stances where you have plugins, how could you restrict the plugin JAR only. Because it's possible that we may have other libraries (ORM, Gson, etc) that depend on reflection.Respectable
T
1

As long as we dont provide security manager, private members of class can be accessible. To access private members of class you should set setAccessible(true), this will allow you to access private members. To restrict access private members Keep below line of code in your immutable class constructor.

System.setSecurityManager(new SecurityManager());

This will throw AccessControlException when you try to set setAccessible(true).

Toothpick answered 16/7, 2018 at 15:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.