views:

264

answers:

2

I'm developer of Robocode engine. We would like to make Robocode multilingual and Scala seems to be good match. We have Scala plugin prototype here.

The problem: Because users are creative programmers, they may try to win battle different ways. As well robots are downloaded from online database where anyone could upload one. So gap in security may lead to security hole into users computer. Robots written in Java are running in restricted sandbox. Almost everything is prohibited [network, GUI, disk (limited), threads (limited), classloaders and reflection]. The sandbox is similar to browser applet. We use SecurityManager, custom ClassLoader per robot, etc ...

There are two ways how to host Scala runtime in Robocode:

1) load it together with robot inside of sandbox. Pretty safe for us, preferred solution. But it will damage Scala runtime abilities because runtime uses reflection. Maybe generates classes at runtime ? Use threads to do some internal cleanup ? Access to JVM/internals ? (I would not like to limit abilities of language)

2) use Scala runtime as trusted code, outside the box, security on same level as JDK. Visibility to (malicious) robot. Are the Scala runtime APIs safe ? Do methods they have security guards ? Is there any safe mode ? Is there any singleton in Scala runtime, which could be abused to communicate between robots ? Any concurency/threadpool/messaging which could simulate threads ? (Is there any security audit for Scala runtime?)

3) Something in between, some classes of runtime in and some out. Which classes/packages must be visible to robot/which are just private implementation ? (this seems to be future solution)

The question: Is it possible to enumerate and isolate the parts of runtime which must run in trusted scope from the rest ? Specific packages and classes ? Or better idea ?

I'm looking for specific answer, which will lead to secure solution. Random thoughts welcome, but not awarded. There is ongoing discussion at scala email group. No specific answer yet.

+2  A: 

I think #1 is your best bet and even that is a moving target. As brought up on the mailing list, structural types use reflection. I don't think structural types are common in the standard library, but I don't think anyone keeps track of where they are.

There's also always the possibility that there are other features using reflection behind the scenes. For example, for a while in the 2.8 branch some array functionality was using reflection. I think that's been changed after benchmarking, but there's always the possibility that there's some problem where someone said "Aha! I will use reflection to solve this."

The Scala standard library is filled with singletons. Most of them are immutable, but I know that the Scheduler object in the actors library could be abused for communication because it is essentially a proxy for an actual scheduler so you can plug your own custom scheduler into it.

At this time I don't think Scala requires using a custom class loader and all of its classes are produced at compile time instead of runtime, but then again that's probably a moving target. Scala generates a lot of class files, and there is always talk of making it generate some of them at runtime when they are needed instead of at compile time.

So, in short, I do not think it's possible (within reasonable constraints on effort) to enumerate and isolate the pieces of Scala that can (and should) be trusted.

Erik Engbrecht
Link to thread about reflection and arrays: http://thread.gmane.org/gmane.comp.lang.scala.internals/2590
Erik Engbrecht
Several good points here. Regarding moving target, u r right, I'm happy to lock down on single version of scala. Regarding "Aha! I will use reflection to solve this." that's criminal act. I would not like to see my users/newbies complaining at our support group about broken runtime which we don't own. It's not clear to me if the runtime will at least wrap/convert the exception to something consistent. Does it at least AccessController.doPrivileged() for such actions ?
Pavel Savara
You have to consider the market Scala targets. Reflection is pretty much ubiquitous in Java web frameworks and JVM-based dynamic languages. It's rather minor compared to runtime bytecode manipulation, which is common as well.Also keep in mind that the use of reflection isn't necessarily restricted to the runtime or library, per se, but rather the compiler simply emits calls within normal user code.I can't find a single instance of AccessController in the Scala source, so I don' think it is at all aware of such things.
Erik Engbrecht
Erik, thanks a lot for your time. I'm sad about my conclusion that scala is no-go for robocode. 2) or 3) is not possible. 1) will cause so much non-deterministic and unexpected pain for users, that I rather don't provide it at all. I do understand that there is no good business reason for investment into security. Except maybe scala in browser applets ? Or that's dead technology already ? Cheers!
Pavel Savara
Scala works in applets (although the jars may take a bit of time to load ;-) and in Google AppEngine. I think for the most part it's your ban on reflection that blocks Scala. Actors wouldn't work, too, because they spawn threads, but people could just not use actors.
Erik Engbrecht
We learned something new with Alex from Robocode community. 1) we don't ban (and should not ban) reflection on public types. 2) GoogleAppEngine alows even calls to setAccessible() on private members as long as they are in scope of user code. I have no idea how they do it. Maybe they have custom JDK, which we don't have. Definitely it's expensive http://jira.codehaus.org/browse/JRUBY-4246Alex asks his question here http://stackoverflow.com/questions/2315066/is-there-a-way-for-a-securitymanager-in-java-to-selectively-grant-reflectpermissi
Pavel Savara
A: 

As you mentioned other J* language implementations which all may make use of reflections, it would be a ban for all those languages as long as reflection is not part of the game. I guess that would be JVM's problem not to have a way to partition the scope of reflection API, such that you could sort of "sandbox" the part of code that could be reflected within.

itsnotvalid
Yep, I think you head to similar direction as GAE comment above.
Pavel Savara
I thought I was writing a comment, but actually I don't have the rights to comment on answers posted by others.
itsnotvalid