2

For an open-source multiplayer programming game written in Scala that loads players' bot code via a plug-in system from .jar files, I'd like to prevent the code of the bots from doing harm on the server system by running them under a restrictive SecurityManager implementation.

The current implementation uses a URLClassLoader to extract a control function factory for each bot from its related plug-in .jar file. The factory is then used to instantiate a bot control function instance for each new round of the game. Then, once per simulation cycle, all bot control functions are invoked concurrently to get the bot's responses to their environment. The concurrent invocation is done using Akka's Future.traverse() with an implicitly provided ActorSystem shared by other concurrently operating components (compile service, web server, rendering):

val future = Future.traverse(bots)(bot => Future { bot.respondTo(state) })
val result = Await.result(future, Duration.Inf)

To restrict potentially malicious code contained in the bot plug-ins from running, it appears that following the paths taken in this StackOverflow question and this one I need to have the bot control functions execute in threads running under an appropriately restrictive SecurityManager implementation.

Now the question: how can I get Akka to process the work currently done in Future.traverse() with actors running in threads that have the desired SecurityManager, while the other Actors in the system, e.g. those running the background compile service, continue to run as they do now, i.e. unrestricted?

Community
  • 1
  • 1
Scalatron
  • 43
  • 4

1 Answers1

0

You can construct an instance of ExecutionContext (eg. via ExecutionContext.fromExecutorService) that runs all work under the restrictive security manager, and bring it into the implicit scope for Future.apply and Future.traverse.

If the invoked functions do not need to interact with the environment, I don't think you need a separate ActorSystem.

Gerolf Seitz
  • 121
  • 4
  • Sorry for being a total Akka newbie, but how am I supposed to do this? `ExecutionContext.fromExecutorService()` expects an `ExecutorService` ; what should I pass? Wouldn't I have to somehow grab an `ExecutorService` from the existing `ActorSystem` and reconfigure it to use a new `SecurityManager`? Not sure how I can make this happen, not least because the sources for Akka do not even appear to contain the string `setSecurityManager`, which is probably what would need to happen here. Do I need to roll my own `ExecutorService`? – Scalatron May 05 '12 at 05:27
  • `java.util.concurrent.ExecutorService` comes with the Java standard library. You can use one of the factory methods on `java.util.concurrent.Executors` like `Executors.newFixedThreadPool(5, new ThreadFactory { def newThread(r: Runnable) = new MyRestrictiveThread(r) })` to create an `ExecutorService` which uses your custom restrictive `Thread` implementations to run the tasks. – Gerolf Seitz May 05 '12 at 06:25
  • I did some research, and this is insecure -- the sandbox can't be set per thread, but per CodeSource. Please see https://tersesystems.com/2015/12/22/an-easy-way-to-secure-java-applications/ and https://tersesystems.com/2015/12/29/sandbox-experiment/ for more details. – Will Sargent Jan 05 '16 at 16:03