Przyjęta odpowiedź jest niepoprawna: nie można zdefiniować strategii bezpieczeństwa, która uniemożliwi tworzenie kodu i uruchomienie nowego wątku przy użyciu standardowego oprogramowania Java SecurityManager.
Powiedzmy masz następujący kod:
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();
}
}
i go uruchomić za pomocą następującego polecenia:
java -Djava.security.manager -Djava.security.policy==/dev/null Test
to będzie działać dobrze i wyjście:
Secure
Ran
mimo że ustawiliśmy politykę bezpieczeństwa na/dev/null, która przyzna zero uprawnień do dowolnego kodu. Dlatego niemożliwe jest przyznanie mniejszej liczby uprawnień, aby zapobiec tworzeniu tego wątku przez kod.
Dzieje się tak dlatego, że standardowy java.lang.SecuritManager wykonuje tylko kontrolę uprawnień, jeśli kod próbuje utworzyć wątek w katalogu głównym ThreadGroup. Jednocześnie znacznik getThreadGroup programu SecurityManager zawsze zwraca bieżącą grupę wątków wątku, która nigdy nie będzie główną grupą wątków, więc uprawnienia do tworzenia nowego wątku będą zawsze przyznawane.
Jednym ze sposobów obejścia tego jest podklasa java.lang.SecurityManager i nadpisanie metody getThreadGroup w celu zwrócenia katalogu głównego ThreadGroup. Umożliwi to kontrolę nad tym, czy kod może tworzyć wątki na podstawie tego, czy zawiera element java.lang.RuntimePermission "modifyThreadGroup".
Jeśli więc teraz zdefiniować podklasę securityManager następująco:
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;
}
}
a następnie ponownie uruchomić naszą komendę, ale tym razem podając nasz podklasy ThreadSecurityManager:
java -Djava.security.manager=ThreadSecurityManager -Djava.security.policy==/dev/null Test
Dostajemy wyjątek nasza klasa testowa, gdy próbujemy utworzyć nowy wątek:
Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
Jaki język programowania? –
java, dodałem do tematu i opisu. – bastiat