자체 스레드에서 신뢰할 수없는 코드를 실행하십시오. 예를 들어 무한 루프 등의 문제를 방지하고 향후 단계를 더 쉽게 수행 할 수 있습니다. 메인 스레드가 스레드가 완료 될 때까지 기다리도록하고, 너무 오래 걸리면 Thread.stop으로 종료합니다. Thread.stop은 더 이상 사용되지 않지만 신뢰할 수없는 코드는 리소스에 액세스 할 수 없으므로 안전하게 죽일 수 있습니다.
해당 스레드에 SecurityManager 를 설정하십시오 . checkPermission (Permission perm) 을 재정의하는 SecurityManager의 하위 클래스 를 만들어 일부 권한을 제외한 모든 권한에 대해 SecurityException 을 발생시킵니다. 여기에 메소드 및 필요한 권한 목록이 있습니다 . Java TM 6 SDK의 권한 .
사용자 정의 ClassLoader를 사용하여 신뢰할 수없는 코드를로드하십시오. 클래스 로더는 신뢰할 수없는 코드가 사용하는 모든 클래스에 대해 호출되므로 개별 JDK 클래스에 대한 액세스를 비활성화하는 등의 작업을 수행 할 수 있습니다. 할 일은 허용되는 JDK 클래스의 화이트리스트를 갖는 것입니다.
별도의 JVM에서 신뢰할 수없는 코드를 실행할 수 있습니다. 이전 단계에서는 코드를 안전하게 만들 수 있지만, 격리 된 코드가 여전히 할 수있는 한 가지 성가신 일이 있습니다. 가능한 한 많은 메모리를 할당하면 메인 애플리케이션의 가시적 인 공간이 커집니다.
JSR 121 : Application Isolation API Specification 은이 문제를 해결하도록 설계되었지만 안타깝게도 아직 구현되지 않았습니다.
이것은 매우 상세한 주제이며, 나는 대부분이 모든 것을 내 머리 위에 쓰고 있습니다.
그러나 어쨌든 불완전하고 위험에 따라 사용하고 버그가있는 (의사) 코드가 있습니다.
ClassLoader
class MyClassLoader extends ClassLoader {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (name is white-listed JDK class) return super.loadClass(name);
return findClass(name);
}
@Override
public Class findClass(String name) {
byte[] b = loadClassData(name);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassData(String name) {
}
}
보안 관리자
class MySecurityManager extends SecurityManager {
private Object secret;
public MySecurityManager(Object pass) { secret = pass; }
private void disable(Object pass) {
if (pass == secret) secret = null;
}
}
실
class MyIsolatedThread extends Thread {
private Object pass = new Object();
private MyClassLoader loader = new MyClassLoader();
private MySecurityManager sm = new MySecurityManager(pass);
public void run() {
SecurityManager old = System.getSecurityManager();
System.setSecurityManager(sm);
runUntrustedCode();
sm.disable(pass);
System.setSecurityManager(old);
}
private void runUntrustedCode() {
try {
loader.loadClass("customclassname")
.getMethod("main", String[].class)
.invoke(null, new Object[]{...});
} catch (Throwable t) {}
}
}
Thread.stop
Java 라이브러리 코드에 문제가 발생합니다. 마찬가지로 Java 라이브러리 코드에는 권한이 필요합니다. 훨씬 더 허용하는SecurityManager
사용java.security.AccessController
. 클래스 로더는 사용자 코드의 자체 클래스에 대한 액세스도 허용해야합니다.