Jalankan kode tidak tepercaya di utasnya sendiri. Ini misalnya mencegah masalah dengan loop tak terbatas dan semacamnya, dan membuat langkah selanjutnya lebih mudah. Minta utas utama menunggu utas selesai, dan jika terlalu lama, matikan dengan Thread.stop. Thread.stop tidak digunakan lagi, tetapi karena kode tidak tepercaya seharusnya tidak memiliki akses ke sumber daya apa pun, maka akan aman untuk membunuhnya.
Setel SecurityManager di Thread tersebut. Buat subclass SecurityManager yang menggantikan checkPermission (Permission perm) untuk hanya menampilkan SecurityException untuk semua izin kecuali beberapa yang dipilih. Ada daftar metode dan izin yang mereka butuhkan di sini: Izin di Java TM 6 SDK .
Gunakan ClassLoader kustom untuk memuat kode tidak tepercaya. Pemuat kelas Anda akan dipanggil untuk semua kelas yang digunakan kode tidak tepercaya, sehingga Anda dapat melakukan hal-hal seperti menonaktifkan akses ke setiap kelas JDK. Hal yang harus dilakukan adalah memiliki daftar putih kelas JDK yang diizinkan.
Anda mungkin ingin menjalankan kode tidak tepercaya di JVM terpisah. Meskipun langkah-langkah sebelumnya akan membuat kode aman, ada satu hal menjengkelkan yang masih dapat dilakukan oleh kode yang diisolasi: mengalokasikan memori sebanyak mungkin, yang menyebabkan footprint yang terlihat dari aplikasi utama bertambah.
JSR 121: Spesifikasi API Isolasi Aplikasi dirancang untuk mengatasi hal ini, tetapi sayangnya belum ada penerapannya.
Ini adalah topik yang cukup mendetail, dan saya kebanyakan menulis ini semua dari atas kepala saya.
Tapi bagaimanapun, beberapa kode yang tidak sempurna, gunakan dengan risiko Anda sendiri, mungkin buggy (pseudo):
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) {
}
}
Manajer keamanan
class MySecurityManager extends SecurityManager {
private Object secret;
public MySecurityManager(Object pass) { secret = pass; }
private void disable(Object pass) {
if (pass == secret) secret = null;
}
}
Benang
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
akan menyebabkan masalah pada kode pustaka Java. Demikian pula, kode pustaka Java akan membutuhkan izin. Jauh lebih baik untuk memungkinkanSecurityManager
penggunaanjava.security.AccessController
. Pemuat kelas mungkin juga harus mengizinkan akses ke kelas kode pengguna itu sendiri.