为什么java安全管理器不禁止创建新的Thread()也不禁止它?

你碰巧知道解释为什么java安全管理器不禁止创建新线程或启动它们吗? 新的FileWriter在安全管理器下,但新的Thread()和threadInstance.start()都不是更安全的安全管理器,并且可以调用。

  1. 禁止它会不会有用吗?
  2. 难以实施吗?
  3. 或者创建和启动新线程并不是那么禁止它?

在Thread构造函数中执行访问检查,以查看调用者是否有权更改将添加新线程的ThreadGroup。 这就是您如何实施安全策略以禁止创建新线程。

(还有一个关于创建ThreadGroups的检查…检查你是否有权将新组添加到其父组。)

所以回答你的问题:

为什么java安全管理器不禁止创建新的Thread()或启动它?

原因是您的JVM当前安全策略允许父线程修改其ThreadGroup 。 您应该能够修改该策略设置以防止这种情况,从而阻止创建子线程。

禁止它会不会有用吗?

它是。 允许不受信任的代码创建/启动线程是不明智的,因为:1)一旦启动的线程无法安全地被杀死,2)创建/启动大量线程可能会使JVM(可能是操作系统)陷入困境。

难以实施吗?

从您的角度来看,只需更改策略即可。

接受的答案是错误的:无法定义将阻止代码使用标准Java SecurityManager创建和启动新线程的安全策略。

假设您有以下代码:

 public class Test { public static void main(String [] args) { System.out.println(System.getSecurityManager() != null ? "Secure" : ""); Thread thread = new Thread( new Runnable() { public void run() { System.out.println("Ran"); } }); thread.start(); } } 

然后使用以下命令运行它:

 java -Djava.security.manager -Djava.security.policy==/dev/null Test 

它会运行得很好并输出:

 Secure Ran 

即使我们将安全策略设置为/ dev / null,它将为任何代码授予零权限。 因此,不可能授予较少的权限来阻止代码创建该线程。

这是因为标准java.lang.SecuritManager仅在代码尝试在根ThreadGroup中创建线程时才执行权限检查。 同时,SecurityManager的getThreadGroup mehtod总是返回当前Thread的线程组,它永远不会是根线程组,因此将始终授予创建新线程的权限。

解决此问题的一种方法是inheritancejava.lang.SecurityManager并重写getThreadGroup方法以返回根ThreadGroup。 这将允许您控制代码是否可以根据它是否具有java.lang.RuntimePermission“modifyThreadGroup”来创建线程。

因此,如果我们现在定义SecurityManager的子类,如下所示:

 public class ThreadSecurityManager extends SecurityManager { private static ThreadGroup rootGroup; @Override public ThreadGroup getThreadGroup() { if (rootGroup == null) { rootGroup = getRootGroup(); } return rootGroup; } private static ThreadGroup getRootGroup() { ThreadGroup root = Thread.currentThread().getThreadGroup(); while (root.getParent() != null) { root = root.getParent(); } return root; } } 

然后再次运行我们的命令,但这次指定我们的子类ThreadSecurityManager:

 java -Djava.security.manager=ThreadSecurityManager -Djava.security.policy==/dev/null Test 

当我们尝试创建新线程时,我们在Test类中遇到exception:

 Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")