Как сделать песочницу для кода запуска другого приложения (начал использовать Process.Start)? - PullRequest
0 голосов
/ 18 марта 2019

Я слышал о песочнице и как сделать простой пример, используя 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.

Я надеюсь получить несколько предложений, конечно, лучше, если у меня есть правильное решение для этого, спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...