最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Suitable language for running client code in sandbox - Stack Overflow

programmeradmin6浏览0评论

I want to simulate (unsafe) client code on my server, and I am looking for a suitable language to do so. I'd prefer having the clients write in the same language as I will use to simulate.

  • safety is the primary concern
  • preferably a well known language (easy for clients to learn syntax)
  • should be easy to disable/enable language features useable in the sandbox
  • would be a plus if I could actually simulate the code step by step

Ideally I would simply construct a few interfaces (and publish these), load the clients code, and simulate that code by allowing it to only use my interfaces + a subset of the standard API I carefully selected.

During this simulation I should be able to limit resources (time and memory) used by the clients code. Bonus would be if I could simulate the code step by step, that way I could always return a deterministic solution.

Performance is not really an issue. The idea is to allow clients to write a custom AI for a small game/puzzle. The game would be simulated (on the server!) and the result returned to the user.

Originally I was thinking of constructing an external DSL myself, including a parser and evaluator, but perhaps there is a ready-to-use solution out there?

I want to simulate (unsafe) client code on my server, and I am looking for a suitable language to do so. I'd prefer having the clients write in the same language as I will use to simulate.

  • safety is the primary concern
  • preferably a well known language (easy for clients to learn syntax)
  • should be easy to disable/enable language features useable in the sandbox
  • would be a plus if I could actually simulate the code step by step

Ideally I would simply construct a few interfaces (and publish these), load the clients code, and simulate that code by allowing it to only use my interfaces + a subset of the standard API I carefully selected.

During this simulation I should be able to limit resources (time and memory) used by the clients code. Bonus would be if I could simulate the code step by step, that way I could always return a deterministic solution.

Performance is not really an issue. The idea is to allow clients to write a custom AI for a small game/puzzle. The game would be simulated (on the server!) and the result returned to the user.

Originally I was thinking of constructing an external DSL myself, including a parser and evaluator, but perhaps there is a ready-to-use solution out there?

Share Improve this question edited Jan 30, 2013 at 11:58 Antiz asked Jan 21, 2013 at 2:20 AntizAntiz 1,4742 gold badges13 silver badges20 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 5 +25

My choice would be to use some scripting language that can be used without automatically providing access to some extensive framework (like .Net or Java) - it is easier to add features than to limit them. Game engine scripting languages like LUA may be an option and usually e with implementations for multiple platforms to use them in.

General considerations:

Whatever language/framework you pick, make sure you can recover from/accept risk of:

  • fatal exceptions (like stack overflow due to recursive functions)
  • unbounded memory allocations/ out of memory exceptions
  • long running tasks

Beware of exposing APIs that allow users to create new threads/tasks/synchronization objects (locks/semaphores) outside of your control or building on platform that provides such API. Allowing such methods may open resources of your server to unlimited consumption or DOS/deadlocks...

Note that long running tasks is a problem with any reasonable language as you can't determine if a program ever ends by looking at it - halting problem. You have to figure out a solution no matter what platform you choose.

.Net/C#:

You can check out Terrarium which does exactly this in .Net - running untrusted code on user's machine in a sandboxed environment.

.Net provides a way to restrict usage of multiple APIs - How to: Run Partially Trusted Code in a Sandbox is a good starting point. Note that as @Andrew points out it is good idea to verify if an assembly provided by a user (either directly or piled from user's sources) does not use APIs that you don't like (or even the other way around - uses just APIs that you do allow) in addition to basic sandboxing. Partially trusted code running in a separate AppDomain gives you ok protection from not-too-hostile code.

Stack overflows are hard to prevent in general and require a custom host to handle in .Net. Long running tasks can be terminated with Thread.Abort or shutting down the AppDomain with the user's code.

Java has the concept of SecurityManager which enables you to fine tune what can or cannot run in your virtual machine.

It also allows you to pile code and load the resulting classes at runtime. You can then run whatever code is in those classes, provided the SecurityManager does not throw a SecurityException because the operation is not permitted.

This post shows a contrived example that piles, loads and runs some code (provided as text source code) at runtime.

This other post gives directions to run untrusted (and potentially malicious) code.

If you want to run code provided by your end users, and you want it to use a language they likely already know, why not JavaScript?

It's possible to sandbox JavaScript in a WebWorker (a concurrent thread that's isolated from the main JavaScript app and has no access to shared memory or globals such as the Window object and the DOM, and only a single avenue for munication with the main thread).

The only security issue I can think of would be limiting the hardware resources consumed by one, but I haven't looked into that -- it may very well be possible with one of the JavaScript runtimes. You'd also want to find a way to prevent one WebWorker from spawning additional ones. You'd have to add some extra code to make sure someone's WebWorker gets automatically shut down after a certain amount of time.

I haven't tried serverside WebWorkers yet, but from the looks of it NodeJS, Rhino, and PhantomJS all support it. Node and Rhino provide different environments than a typical web browser while PhantomJS is a full browser engine (WebKit) running headless. From the perspective of a WebWorker, they'd probably all look the same.

I would remend .NET (C#, VB and F#). You can take advantage of the JIT to have a server programmatically pile code, use reflection to analyze it, and have each client run in a separate AppDomain for security and code isolation.

If you really want "well known", ADsafe is a subset of JavaScript that's effectively sandboxed, though it has a few quirks (e.g. avoiding this).

Java has "class loaders" which can restrict the classes that a class has access to (see SecureClassLoader). I'm a bit hazy on the details, but it's essentially what's used to provide Java applet security. I don't know if it can restrict memory usage, but restricting CPU time is not too difficult (don't let it spawn threads and kill the thread running the untrusted code after a timeout).

(I am fondly reminded of Robocode which runs untrusted AI attempting to kill other untrusted AI within the constraints of the game. The main difference is that it was intended to run on end-users' puters, though there were sites doing automated ranking. It was my introduction to Java, though I note that it now supports .NET, probably due to the similarity of the two languages.)

发布评论

评论列表(0)

  1. 暂无评论