Reputation: 390
Is it possible to sandbox my Runnable within Java? Given a Runnable, I want the code inside of it (along with whatever threads it spawns) to run in a sandbox that only lets the code access a specific path on the fileystem. Once that Runnable finishes, the thread should go back to whatever normal permissions it had while any remaining spawned threads would still have the filesystem restriction applied.
I want to do this at run-time. That means that I want to avoid creating policy files and passing in custom arguments to the JVM. I've so far been able to apply sandboxing to my entire application but I haven't found a way to scope it to just the Runnable running in the current thread...
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
CodeSource nullSource = new CodeSource(null, (CodeSigner[]) null);
PermissionCollection perms = new Permissions();
perms.add(new FilePermission(path.toAbsolutePath().toString() + "/*", "read"));
ProtectionDomain domain = new ProtectionDomain(nullSource, perms);
AccessControlContext safeContext = new AccessControlContext(
new ProtectionDomain[]{domain});
AccessController.doPrivileged((PrivilegedAction) () -> {
try {
r.run();
} catch (Exception e) {
throw new IllegalStateException(e);
}
return null;
}, safeContext);
Upvotes: 3
Views: 361
Reputation: 147154
The doPrivileged
technique of limiting permissions applies only to trusted code that does not abuse its position (for instance, by calling doPrivileged
itself). So useful as a layer against XML inclusion, for instance, but not untrusted plugins.
You can load code at runtime with specific permissions using a custom ClassLoader
, but you would have to reload the code if you wanted the permissions.
The Object Capability Model gives a 'pure' dynamic solution. The container passes the plugin an object that is capable of performing the privileged action. Internally the object's methods can just be the action surrounded by a doPrivileged
. Crucially the actions are only available through an instance and unprivileged code is not permitted to instantiate it. This is similar to, say, FileOpenService
in JNLP/WebStart, if you ignore ServiceMangaer
. Internal to the JDK you may see the likes of Unsafe
and SharedSecrets
, although those are more about avoiding repeated security checks.
Upvotes: 3