反思安全

nic*_*las 8 java security reflection policy securitymanager

如何通过不允许执行反射安全Method,Field,Constructor对象调用setAccessible(true)?SecurityPolicy文件还是其他什么?

通常,对于独立的Java应用程序,没有SecurityManager注册.

我用这个 System.setSecurityManager(new SecurityManager());

这种方法适用于调用方法.

我想强制执行使用jar的整个jar或客户端代码不允许调用 setAccessible(true);

有更好的方法吗?

谢谢.

eis*_*eis 5

嗯,它确实适用于 setAccessible。看:

class A {
  private String method1() {
    return "Hello World!";
  }
}
Run Code Online (Sandbox Code Playgroud)

import java.lang.reflect.Method;

class B {
  public static void main(String[] args) throws Exception {
    System.setSecurityManager(new SecurityManager());
    Class clazz = A.class;
    Method m = clazz.getDeclaredMethod("method1");
    m.setAccessible(true);
  }
}
Run Code Online (Sandbox Code Playgroud)

结果是

Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
        at java.security.AccessControlContext.checkPermission(Unknown Source)
        at java.security.AccessController.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPermission(Unknown Source)
        at java.lang.reflect.AccessibleObject.setAccessible(Unknown Source)
        at B.main(B.java:8)
Run Code Online (Sandbox Code Playgroud)

它可能对您不起作用的一个原因是,根据这篇文章中的评论,它过去不能在 Java 1.5 中工作,但可以在 6 及之后的版本中工作。


编辑:要为特定的 jar 拒绝它,您需要使用策略文件,例如:

// specific file
grant codeBase "file:/test/path/tools.jar" {
  // no permissions for this one
};

// default to giving all
grant {
  permission java.security.AllPermission;
};
Run Code Online (Sandbox Code Playgroud)

有两种指定策略文件的方法,要么将其作为默认值的添加项,要么仅提供指定的那些 ( source ):

如果你使用

java -Djava.security.manager -Djava.security.policy==someURL SomeApp
Run Code Online (Sandbox Code Playgroud)

(注意双等号)然后只使用指定的策略文件;安全属性文件中指示的所有内容都将被忽略。

...或者实现一个自定义的安全管理器,这看起来并不难。不过自己没做过。