Вопрос

We are building an engine that will allow us to add new jar files whenever, load those jar files and look for some specific functionality, and run the code that exposes that functionality. Current plan is to use the ServiceLoader to do so (just an extra detail; I'm not married to that idea). For the moment let's assume that we completely control which jar files are going to be loaded (big assumption--I'd guess I'm going to eventually post something about that too).

Given all that, I would like to restrict access in those extensions to certain classes. For a fake example, we want to ensure that instead of using java.io.PrintStream, they use our.better.PrintStreamSolution.

I really don't have a good idea of what I could do here. Since for the time being, we own the code that will go out as extensions, we could just do very thorough code reviews but I'd rather do either a static analysis at install time or actually throw errors at runtime. Any idea how one would would accomplish this?

Это было полезно?

Решение

You would need to whitelist the APIs. Reflective APIs appear all over the place, so you can't realistically blacklist. To do this, you'd need to go through the jars using a library such as ASM. Whilst you could use URLClassLoader with a custom URL connection handler, I would suggest a custom class loader. I strongly suggest avoiding anything to do with global state, such as ServiceLoader.

Другие советы

Create a special ClassLoader to read the JAR, and override the method "loadClass" so that if the classloader tries to load a class from the "java.io" package, it throws SecurityException. Something like this:

protected Class loadClass(String name, boolean resolve)
                                            throws ClassNotFoundException { 
       if (name.startsWith("java.io")) 
             throw new SecurityException("java.io access not allowed on extensions");

        return super.loadClass(name,resolve); 
} 

Remember to implement your classloading logic in the overriden findClass method of your ClassLoader.

This check can be defeated if the extension can get hold of another classloader (like the system classloader) to load the 'forbidden' classes.

As shown in the comments, the alternative to use SecurityManager is possible only if the security manager can identify that a package is being accesed from within an extension.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top