>在自己的线程中运行不受信任的代码。这例如防止无限循环等的问题,并且使得未来的步骤更容易。让主线程等待线程完成,如果花费太长时间,用Thread.stop杀死它。 Thread.stop已被弃用,但由于不受信任的代码应该不能访问任何资源,因此可以安全地杀死它。
>在该主题上设置一个
SecurityManager。创建一个SecurityManager的子类,覆盖
checkPermission(Permission perm),只为所有权限抛出一个
SecurityException,除了少数几个。有一个方法列表和他们需要的权限:
Permissions in the JavaTM 6 SDK。
>使用自定义的ClassLoader加载不受信任的代码。你的类加载器将被调用的不受信任的代码使用的所有类,所以你可以做的事情,如禁用访问单个JDK类。要做的事情是有一个允许的JDK类的白名单。
>您可能希望在单独的JVM中运行不受信任的代码。虽然前面的步骤会使代码安全,但孤立代码仍然可以做到:分配尽可能多的内存,这会导致主应用程序的可见空间增长。
这是一个非常详细的主题,我大多是把这些都写在我的头顶。
但无论如何,一些不完美,使用自己的风险,可能是buggy(伪)代码:
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) {
// load the untrusted class data here
}
}
SecurityManager
class MySecurityManager extends SecurityManager {
private Object secret;
public MySecurityManager(Object pass) { secret = pass; }
private void disable(Object pass) {
if (pass == secret) secret = null;
}
// ... override checkXXX method(s) here.
// Always allow them to succeed when 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 {
// run the custom class's main method for example:
loader.loadClass("customclassname")
.getMethod("main", String[].class)
.invoke(null, new Object[]{...});
} catch (Throwable t) {}
}
}