0

I am trying to build a web application (running on Linux servers) in which the user will upload an executable, the executable will be ran against a particular input available on the server (fed via STDIN), and the output (read from STDOUT) will be returned to the user.

Of course, I do not want the user to be able to do anything malicious on my server. I would like to run the executable in a sandbox, or otherwise prevent the executable from executing sensitive system calls.

I have no idea where to start from. I checked out User-Mode Linux, but it seems to have too much overhead (many executables will be running in parallel, and having a VM for each one is way too much overhead).

How should I proceed?

Edit: I understand this is something one normally avoids. I understand there are risks. Consider this as something you would do for the sake of learning how it can be done. I have seen it done before on places like CodePad and geordi, sometimes it is a very convenient thing to do.

7
  • Not much of a learning experience if someone else just tells you how to do it...
    – womble
    Nov 27, 2009 at 21:50
  • Oh, and have you even bothered to read the about page on codepad.org?
    – womble
    Nov 27, 2009 at 21:51
  • 1
    Yes. I spent the last 3 hours trying to figure out how he used geordi to do what he has done, with no luck whatsoever. I thus turned to ServerFault. Nov 27, 2009 at 21:54
  • 1
    I am not asking for someone to "tell me how to do it", I just asked "how to proceed". I am stuck. I just need a direction to start with. Nov 27, 2009 at 21:57
  • E-mail the person behind codepad.org and ask them.
    – womble
    Nov 27, 2009 at 22:09

5 Answers 5

4

You're taking a massive, massive risk running untrusted code. I would completely rethink both what I wanted to do and the fundamental assumptions of my project if the answer to my problem I came up with was "run untrusted code from arbitrary users on my server".

3
  • Others have done it, and it works. Checkout www.codepad.org :) Nov 27, 2009 at 21:31
  • Done it, yes. Works... not so much. I'm pretty sure I've got enough info out of that service to confirm a hole, but I'm not one to go crashing machines at a whim -- and I'm not even particularly good at breaking into things.
    – womble
    Nov 27, 2009 at 21:55
  • I am interested to see what you found. Could you please link to the pastie you ran? Nov 27, 2009 at 22:00
4

You can give a try to librestrict.

It is a small library designed to be LD_PRELOAD-ed before starting a given executable, basically works by chroot()ing into a given directory, then removing all capabilities (except ones based on a whitelist) then setuid()-ing to a given user, preventing the given executable from doing nasty things.

One of the beauties of this program is that it chroot()s after the system has loaded all the necessary libraries, therefore if you are lucky (it does not want to dl() some other libs) you can use it with an empty directory, as a chroot() environment.

Though, it's a bit old and undocumented, you can give it a try, I can give you a hand.

2
  • This is unsafe. Don't do it. LD_PRELOAD is a request, not a demand... an arbitrary user-supplied executable can easily inline system calls (int 0x80 or similar) and LD_PRELOAD will be none the wiser.
    – user15323
    Nov 30, 2009 at 6:04
  • what kind of system calls are you afraid of?
    – asdmin
    Nov 30, 2009 at 18:07
2

I think running executables in a VM is your best bet. For example, there's a bot on the #bash IRC channel that allows for the execution of arbitrary shell code...by running it inside a qemu based VM and then capturing the stdout of that process. UML is probably a reasonably good solution.

The new lguest stuff (http://lguest.ozlabs.org/) is probably better; this is "container" mechanism, rather than a full-on "virtualization" solution; something like Solaris Zones. I don't know what the state of this project is right now.

1

Does it have to be an executable file? Could you restrict uploaded programs to be for example source code in some scripting language (python, ruby) which have some kind of sandbox executing environment. Or bytecode for something like C# or Java? At least C# and Java have built in security mechanism for allowing and disallowing operations.

You could then more easily restrict what the uploaded programs can do and cannot do.

1
  • Well yes, it can be a scripting language. I actually started off by allowing just Ruby and sandboxing it, but I was wondering how this could be generalized, thus giving more options to my users. Nov 28, 2009 at 13:41
0

I tried something similar, and have chosen grsecurity-enabled kernel plus read-only bind mounts for sharing system files between host and sandbox. Then the testing app was started in chroot-ed sandbox. When done, all processes belonging to sandbox user are killed with SIGKILL and any user-modifiable files erased and replaced from original. While it may not be so completely safe as virtual machine it comes very close when done right. The advantage is much less overhead.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .