Şu anda güvenilir kodun güvenilmeyen kodla birlikte çalıştırılması gereken küçük bir Java uygulaması geliştirmeye çalışıyorum. Bunu başarmak için, SecurityException
s özelliğine izin verilen bir özel SecurityManager
yükledim.Özel GüvenlikManager'ım neden Constructor.newInstance ile bir nesne oluşturduğumda 16. kez istisnalara neden oluyor?
Güvenilmeyen ve güvenilmeyen kod arasında bir köprü olarak, güvenilmeyen bir nesnenin nesnesini başlatmak için Constructor.newInstance()
kullanan bir iş parçacığım var. Bu çağrıyı yaptığı sırada güvenlik yöneticisi her şeyi engellemek üzere yapılandırıldı. İlginç bir şekilde, Constructor.newInstance()
kullanarak nesneler oluşturmaya çalıştığım ilk 15 kez, her şey iyi çalışıyor, ancak 16 kez SecurityException
aldım.
Ben basit bir test programına bu aşağı almak başardınız:
import java.lang.reflect.*;
import java.security.*;
public class Main {
/* Track how many instances have been created so that we can see when the exception
* is thrown.
*/
private static int numInstances = 0;
public Main() {
System.out.println("Number created: " + ++numInstances);
}
public static void main(String[] args) {
/* Get the constructor for Main so that we can instantiate everything
* later on.
*/
Constructor<Main> ctor;
try {
ctor = Main.class.getConstructor();
} catch (NoSuchMethodException e) {
e.printStackTrace();
return;
}
/* Install a super prohibitive security manager that disallows all operations. */
System.setSecurityManager(new SecurityManager() {
@Override
public void checkPermission(Permission p) {
/* Nothing is allowed - any permission check causes a security
* exception.
*/
throw new SecurityException("Not permitted: " + p);
}
});
/* Continuously create new Main objects. */
try {
while (true) {
ctor.newInstance();
}
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
Bu program, checkPermission
bağımsız olarak her zaman isteneni izni bir hata atan SecurityManager
yükler. Daha sonra bir döngüde oturur ve bugüne kadar üretilen örneklerin sayısını yazdırmaya yarayan zararsız bir Main
nesnesini başlatmak için ctor.newInstance()
kullanır. aşağıdaki gibi bu programın çıktısı, benim sistemde, geçerli:
Bu hibe son derece tehlikeli bir izindir:
Number created: 1 Number created: 2 Number created: 3 Number created: 4 Number created: 5 Number created: 6 Number created: 7 Number created: 8 Number created: 9 Number created: 10 Number created: 11 Number created: 12 Number created: 13 Number created: 14 Number created: 15 java.lang.SecurityException: Not permitted: ("java.lang.RuntimePermission" "createClassLoader") at Main$1.checkPermission(Main.java:32) at java.lang.SecurityManager.checkCreateClassLoader(SecurityManager.java:611) at java.lang.ClassLoader.checkCreateClassLoader(ClassLoader.java:274) at java.lang.ClassLoader.<init>(ClassLoader.java:316) at sun.reflect.DelegatingClassLoader.<init>(ClassDefiner.java:72) at sun.reflect.ClassDefiner$1.run(ClassDefiner.java:60) at sun.reflect.ClassDefiner$1.run(ClassDefiner.java:58) at java.security.AccessController.doPrivileged(Native Method) at sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:57) at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:399) at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:396) at java.security.AccessController.doPrivileged(Native Method) at sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:395) at sun.reflect.MethodAccessorGenerator.generateConstructor(MethodAccessorGenerator.java:94) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:48) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:526) at Main.main(Main.java:39)
the Javadoc for
RuntimePermission
göre,createClassLoader
izni vermek için riskli bir tanesidir. Kendi sınıf yükleyicilerini başlatabilecek kötü niyetli uygulamalar, kendi haydut sınıflarını sisteme yükleyebilir. Bu yeni yüklenen sınıflar, sınıf yükleyici tarafından herhangi bir koruma alanına yerleştirilebilir, böylece sınıflar otomatik olarak o alan için izinleri verir.
özellikle bu hataya neden olduğunu Ne:
iki soru var? Neden 16'ncı saatte bir sınıf yükleyicisi için istek aldım? Bunun, nesnenin doğrudan örneğini oluşturmak için bayt kodu oluşturarak yansımayı optimize etmeye çalışan Java ile ilgili olması gerektiğinden şüpheleniyorum, fakat emin değilim.
Tehlikeli olan createClassLoader
ayrıcalığını beyaz listeye almaksızın güvenilmeyen koddan güvenilmeyen nesneleri başlatmanın bir yolu var mı? Temel olarak bu yanlış yola yaklaşıyor muyum?
Teşekkürler!
Kodunuzu aynı davranışta denedim. Throw özel durumunu kaldırırsanız ve bir print ifadesi eklerseniz, 16 örneğini oluşturmadan önce 'checkPermission '3 kez çağrılır. –