简体   繁体   中英

Can I load a Java class in a way that automatically removes its privileges?

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:

  • Clients of the library requests a class from a remote source.
  • My library instantiates that object, then returns it to the user.

This is a major security risk, since the untrusted code can do just about anything. To address this, my library has the following design:

  • I enable the SecurityManager and, when instantiating the untrusted object, I use an AccessController to handle the instantiation in a context where there are no privileges.
  • Before returning the object back to the client, I wrap the object in a decorator that uses an 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:

  • If the wrapped object has any methods that return objects, those returned objects have to themselves be wrapped.
  • The wrapper code will potentially be thousands of lines long, since every exported method has to be secured.
  • All of the methods exported by the downloaded object have to be known in advance in order to be wrapped.

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!

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(...) .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM