I plan to design a system that will essentially allow users to run scripted code like PHP, Ruby, etc. on my machines. I would like to sandbox them from accessing critical aspects of the machines. What .NET API's could be used for this? I plan to create a sub-process from a main process and would like to sandbox the sub-process programmatically from the main one. Thanks.
问题:
回答1:
Designing a (user-mode) sandbox is a difficult challenge that requires in-depth knowledge of the underlying operating system (or in other words: using an existing solution might be preferable over re-inventing the wheel).
The isolations levels exising in .NET such as AppDomains don't fit your scenario. You need to start at a lower level and might consider one of the following approaches to run your application with restricted access to your host.
Windows Integrity Mechanism
A simple way to run a program with restricted access to the system is to make use of the Windows integrity mechanism, which is one of the ways e.g. Internet Explorer or Microsoft Office in Protected Mode are isolated. This mechanism is not designed to provide a fully isolated sandbox, but may be sufficient in basic cases. The documentation states:
The Windows integrity mechanism is not intended as an application sandbox. However, it can be one of the security tools that application developers use to restrict the behavior of less trustworthy applications.
The integrity mechanism mostly restricts write permissions, but it does not inhibit or prevent reading data at any higher level.
Starting a process with the lowest integrity level is as easy as changing the ACL of the executable image as descibred here and then start the program:
Set the integrity level:
icacls myprogram.exe /setintegritylevel Low
Start the program which now runs at the lowest integrity level (as can be seen using a tool such as Process Explorer):
myprogram.exe
As described in the linked article, you can also start a new process with low integrity programmatically (not using .NET, but by P/Invoking into the Windows API). The article also gives hints on how the low-level program needs to be designed to work (e.g. which locations are writable etc).
Container
Container solutions such as Docker provide a higher level of isolation which is achieved through adding some OS-level barriers, but some resources such as the kernel are still shared (and thus bringing a certain risk of malicious code escaping the sandbox).
Virtualization
Virtualization provides an even higher level of isolation: The entire system runs in an isolated VM and can only be accessed via a dedicated interface (e.g. an open TCP port). The virtualization approach provides highest security and escaping a VM can be considered sufficiently hard for most cases (although vulnerabilities in the hypervisor may exist and may be exploitet using certain rather complex attacks).
The difference to containers is that you start with an almost fully isolated system where you open up only specific, dedicated communication channels to the host system. In contrast, with containers you share the same system and build up barriers as needed to isolate the guest. This has the disadvantage that is it easier to forget something.
The issue is further discussed in a post on the Information Security Stackexchange site: Docker as a sandbox for untrusted code