I am working on developing a library that needs to instantiate and return untrusted objects downloaded from an external website. At a high-level, the library works as follows:
This is a major security risk, since the untrusted code can do just about anything. To address this, my library has the following design:
SecurityManager
and, when instantiating the untrusted object, I use an AccessController
to handle the instantiation in a context where there are no privileges.AccessController
to forward all method requests to the underlying object in a way that ensures that the untrusted code is never run with any permissions.It occurs to me, though, that this might not be the most elegant solution. Fundamentally, I want to strip away all permissions from any object of any type downloaded from the remote source. My current use of AccessController
is simply a way of faking this up by intercepting all requests and dropping privileges before executing them. The AccessController
approach also has its own issues:
My question is this: is there a way to load classes into the JVM (probably using a custom ClassLoader
) such that any instances of those classes execute their methods with no permissions?
Thanks!
Because in Java, a variable of type abc doesn't contain an abc object. A variable of type abc contains a reference to an abc object. Your reasoning would be valid in say C++. But a class can have static object of self type.
The FileInputStream and SecurityManager classes are system classes for which CodeSource is null and permissions consist of an instance of the AllPermission class, which allows all operations.
You will want to call defineClass
with an untrusted ProtectionDomain
.
Your current solution has a number of problems. It doesn't appear to cover the static initialiser. It may be possible to install code into some mutable arguments. Methods that use the immediate caller will still be privileged (AccessController.doPrivileged
, say). But most of all, it falls about when rubbing up against any kind of global - for instance running a finaliser.
Don't know if there's a way to directly do what you asked, but I think your approach can be simplified by using interfaces and dynamic proxies. Basically, if you have an interface for the object to be returned, and all its methods return either simple types or interfaces, then you can wrap all the methods and their return values automatically, without knowing the methods in advance. Just implement an InvocationHandler
that does the AccessController
magic in its invoke method, and create proxies using Proxy.newProxyInstance(...)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With