【问题标题】:Java Security Manager completely disable reflectionJava 安全管理器完全禁用反射
【发布时间】:2017-03-06 06:19:30
【问题描述】:

我已经在 Stackoverflow 上阅读了很多关于这个问题的问题,但无法退出为我的问题找到解决方案或答案。如果已经有一个,如果有人能给出提示,我将不胜感激......

我的问题/问题是是否可以完全禁用不可信代码的反射? getDeclaredMethods() 之类的函数(参见 test.java)。我已经有一个 Java 安全管理器,如果代码尝试写入/读取/等,它会抛出安全异常。 ...

如果可能的话,有人可以告诉我怎么做吗?

布鲁诺

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());
}

【问题讨论】:

    标签: java reflection securitymanager policies


    【解决方案1】:

    所以我没有直接使用 checkPermission() 解决了这个问题。我的解决方法是检查 java.lang.reflect 包是否被访问。

    @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!");
        }
    }
    

    【讨论】:

      【解决方案2】:

      扩展您的 SecurityManager 并让它检查 ReflectPermissionRuntimePermission。然后你必须决定调用者是否有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");
          }
      }
      

      【讨论】:

      • 我复制了你的代码并添加了throw new SecurityException(...),但没有抛出异常......甚至没有调用该函数......
      • 是的,getDeclaredMethods() 不会调用它,但如果您想通过Method.setAccessible(true) 访问私有/受保护的方法,则调用SecurityManager
      • 我更新了答案以检查getDeclardXYZ()。希望对您有所帮助。
      • 它也无法正常工作我不知道为什么,但是甚至没有调用 checkPermission 函数...
      • 策略是全局的还是可以将其设置为特定的包?例如,在你有插件的情况下,你怎么能只限制插件 JAR。因为我们可能有其他依赖于反射的库(ORM、Gson 等)。
      【解决方案3】:

      只要我们不提供安全管理器,就可以访问类的私有成员。要访问类的私有成员,您应该设置 setAccessible(true),这将允许您访问私有成员。限制访问私有成员 在不可变类构造函数中保留以下代码行。

      System.setSecurityManager(new SecurityManager());

      当您尝试设置 setAccessible(true) 时,这将引发 AccessControlException。

      【讨论】:

        猜你喜欢
        • 2010-10-20
        • 2010-12-20
        • 2011-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-16
        相关资源
        最近更新 更多