Принятый ответ неверен: невозможно определить политику безопасности, которая не позволит коду создавать и запускать новый поток с использованием стандартного 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 выполняет проверку разрешений только в том случае, если код пытается создать поток в корневой группе потоков. В то же время метод getThreadGroup SecurityManager всегда возвращает группу потоков текущего потока, которая никогда не будет корневой группой потоков, поэтому разрешение на создание нового потока всегда будет предоставлено.
Один из способов обойти это — создать подкласс java.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
Мы получаем исключение в нашем тестовом классе, когда пытаемся создать новый поток:
Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
person
alphaloop
schedule
25.06.2015