Я слышал о песочнице и как сделать простой пример, используя AppDomain
в .NET, как в этой статье https://docs.microsoft.com/en-us/dotnet/framework/misc/how-to-run-partially-trusted-code-in-a-sandbox
Однако небезопасный (или ненадежный) код, который я здесь выполняю, запускает другой процесс, используя 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, было бы проще, потому что мне, возможно, не придется использовать Process.Start
здесь. Но представленный код Java
или неуправляемый C++
, на самом деле мы должны скомпилировать его в некоторый исполняемый файл и запустить его, используя Process.Start
.
Я надеюсь получить несколько предложений, конечно, лучше, если у меня есть правильное решение для этого, спасибо!