如何对运行另一个应用程序(使用Process.Start启动)的代码进行沙盒处理?

时间:2019-03-18 19:40:27

标签: c# security resources sandbox appdomain

我听说过沙箱以及如何像本文https://docs.microsoft.com/en-us/dotnet/framework/misc/how-to-run-partially-trusted-code-in-a-sandbox一样在.NET中使用AppDomain作一个简单的例子

但是,我在这里执行的不安全(或不受信任)代码是使用Process.Start运行另一个进程的(或者,如果您知道另一种方法来限制对已启动进程的访问,请提出建议)。我的目的是限制已启动进程(可能不是.NET应用程序)的资源访问。因此,例如,启动的进程应该不能在当前环境中访问任何文件。

这里的问题是,我们需要一个安全上下文(由当前AppDomain提供),该上下文必须具有Process.Start的完全信任(不受限制)。 我真的希望当前的部分受信任的上下文(在调用Process.Start之前)可以级联到启动的进程中,并且可以按预期帮助约束资源访问。但是,如果我们需要一个完全信任的上下文来运行Process.Start,那么该操作将在该步骤失败。

我已经没有足够的想法来实现此目标,因为我知道在.NET中运行进程的唯一方法是使用Process.Start,但它需要完全信任的上下文……:(

这是我尝试过的代码,在调用Process.Start之前总是会抛出错误:

class Program
{
    static void Main(string[] args)
    {
        var ads = new AppDomainSetup();
        ads.ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        var ps = new PermissionSet(System.Security.Permissions.PermissionState.None);
        ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
        var ad = AppDomain.CreateDomain("SB", null, ads, ps);

        var sb = ad.CreateInstanceAndUnwrap(typeof(Sandbox).Assembly.FullName, typeof(Sandbox).FullName) as Sandbox;

        //the code throws exception and be highlighted at this line
        sb.ExecuteUnsafeCode();

        Console.WriteLine("End!");
        Console.ReadLine();
    }
}
//the sandbox class
public class Sandbox : MarshalByRefObject
{       
    //this simple method stub is just for testing
    public void ExecuteUnsafeCode()
    {
        try
        {                
            var si = new ProcessStartInfo("someSimpleApp.exe");
            Process.Start(si);

            Console.WriteLine("Run OK!");                
        } catch(Exception ex)
        {
            Console.WriteLine("SecurityException caught:\n{0}", ex.ToString());
        }
    }
}

引发的异常是SecurityException,其中包含非常短的消息Request fail。堆栈跟踪也太短(仅3行),实际上没有任何帮助。

在此,我的主要目的是在沙箱中运行(来自用户的)提交的代码,以使任何恶意代码都不会损害服务器。如果提交的代码是某个.NET lang,那会更容易,因为在这里我不必使用Process.Start。但是提交的代码是Java或非托管的C++,实际上我们必须将其编译成一些可执行文件并使用Process.Start运行。

我希望能得到一些建议来尝试一下,当然,如果我有一个正确的解决方案,那就更好了,谢谢!

0 个答案:

没有答案