我听说过沙箱以及如何像本文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
运行。
我希望能得到一些建议来尝试一下,当然,如果我有一个正确的解决方案,那就更好了,谢谢!