In a simulation server environment where users are allowed to submit their own code to be run by the server, it would clearly be advantageous for any user-submitted code to be run in side a sandbox, not unlike Applets are within a browser. I wanted to be able to leverage the JVM itself, rather than adding another VM layer to isolate these submitted components.
This kind of limitation appears to be possible using the existing Java sandbox model, but is there a dynamic way to enable that for just the user-submitted parts of a running application?
The Java-Sandbox is a library for executing Java code with a limited set of permissions. It can be used to allow access to only a set of white-listed classes and resources. It doesn't seem to be able to restrict access to individual methods. It uses a system with a custom class loader and security manager to achieve this.
I have not used it but it looks well designed and reasonably well documented.
@waqas has given a very interesting answer explaining how this is possible to implement yourself. But it is much safer to leave such security critical and complex code to experts.
Notice though that the project has not been updated since 2013 and the the creators describe it as "experimental". Its home page has disappeared but the Source Forge entry remains.
Example code adapted from the project web site:
Here's a thread-safe solution for the problem:
https://svn.code.sf.net/p/loggifier/code/trunk/de.unkrig.commons.lang/src/de/unkrig/commons/lang/security/Sandbox.java
Please comment!
CU
Arno
You will probably need to use a custom SecurityManger and/or AccessController. For lots of detail, see Java Security Architecture and other security documentation from Sun.
Run the untrusted code in its own thread. This for example prevents problems with infinite loops and such, and makes the future steps easier. Have the main thread wait for the thread to finish, and if takes too long, kill it with Thread.stop. Thread.stop is deprecated, but since the untrusted code shouldn't have access to any resources, it would be safe to kill it.
Set a SecurityManager on that Thread. Create a subclass of SecurityManager which overrides checkPermission(Permission perm) to simply throw a SecurityException for all permissions except a select few. There's a list of methods and the permissions they require here: Permissions in the JavaTM 6 SDK.
Use a custom ClassLoader to load the untrusted code. Your class loader would get called for all classes which the untrusted code uses, so you can do things like disable access to individual JDK classes. The thing to do is have a white-list of allowed JDK classes.
You might want to run the untrusted code in a separate JVM. While the previous steps would make the code safe, there's one annoying thing the isolated code can still do: allocate as much memory as it can, which causes the visible footprint of the main application to grow.
JSR 121: Application Isolation API Specification was designed to solve this, but unfortunately it doesn't have an implementation yet.
This is a pretty detailed topic, and I'm mostly writing this all off the top of my head.
But anyway, some imperfect, use-at-your-own-risk, probably buggy (pseudo) code:
ClassLoader
SecurityManager
Thread
To address the problem in the accepted answer whereby the custom
SecurityManager
will apply to all threads in the JVM, rather than on a per-thread basis, you can create a customSecurityManager
that can be enabled/disabled for specific threads as follows:ToggleSecurirtyManagerPermission
is just a simple implementation ofjava.security.Permission
to ensure that only authorised code can enable/disable the security manager. It looks like this:Well it's very late to give any suggestions or solutions, but still I was facing similar kind of issue, kind of more research oriented. Basically I was trying to provide a provision and automatic evaluations for programming assignments for Java course in e-learning platforms.
I know this sounds a quite complex and lot of tasks, but Oracle Virtual Box already provides Java API to create or clone virtual machines dynamically. https://www.virtualbox.org/sdkref/index.html (Note, even VMware also provides API for doing same)
And for the minimum size and configuration Linux distribution you can refer to this one here http://www.slitaz.org/en/,
So now if students messes up or tries to do it, may be with memory or file system or networking, socket, maximum he can damage his own VM.
Also internally into these VM's you can provide additional security like Sandbox (security manager ) for Java or creating user specific accounts on Linux and thus restricting access.
Hope this helps !!