Насколько уязвимым является выполнение ненадежного кода с ограничением ссылок с использованием AssemblyLoadContext в C# .NET Core

Я пытаюсь запустить ненадежные коды, загруженные пользователем на моем сервере. Мои пользователи хотят писать простые функции, которые будут выполняться на сервере, например:

public class HelloWorldPlugin
{
    public string GetResult(string input)
    {
        //return System.IO.Directory.GetCurrentDirectory();
        return "Hello " + input;
    }
}

Обновление: мне не разрешено использовать докер или подобное изолированное решение из-за их требований к ресурсам.

Шаги следующие:

  • Определение разрешенных сборок и типов

  • Составление пользовательских кодов

  • Загрузка скомпилированной сборки в отдельный AssemblyLoadContext

  • Выполнение пользовательской функции

  • Распоряжение ресурсами

Я упростил свой код, как показано ниже:

public class PluginLoader : IDisposable
{
    private AssemblyLoadContext assemblyLoadContext;
    private Assembly assembly;
    private byte[] bytes;

    public void Load(string id, string code, IEnumerable<string> allowedAssemblyNames, IEnumerable<Type> allowedTypes)
    {
        var _references = new List<MetadataReference>();
        foreach (var assemblyName in allowedAssemblyNames)
        {
            _references.Add(MetadataReference.CreateFromFile(RuntimeEnvironment.GetRuntimeDirectory() + assemblyName + ".dll"));
        }

        foreach (var type in allowedTypes)
        {
            _references.Add(MetadataReference.CreateFromFile(type.Assembly.Location));
        }

        var options = new CSharpCompilationOptions(
            OutputKind.DynamicallyLinkedLibrary,
            reportSuppressedDiagnostics: true,
            optimizationLevel: OptimizationLevel.Release,
            generalDiagnosticOption: ReportDiagnostic.Error,
            allowUnsafe: false);

        var syntaxTree = CSharpSyntaxTree.ParseText(code, options: new CSharpParseOptions(LanguageVersion.Latest, kind: SourceCodeKind.Regular));
        var compilation = CSharpCompilation.Create(id, new[] { syntaxTree }, _references, options);

        assemblyLoadContext = new AssemblyLoadContext(id, true);

        using (var ms = new MemoryStream())
        {
            var result = compilation.Emit(ms);
            if (result.Success)
            {
                ms.Seek(0, SeekOrigin.Begin);
                bytes = ms.ToArray();
                ms.Seek(0, SeekOrigin.Begin);
                assembly = assemblyLoadContext.LoadFromStream(ms);
            }
        }

    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public string Run(string typeName, string methodName, string input)
    {
        var instance = assembly.CreateInstance(typeName);
        MethodInfo theMethod = instance.GetType().GetMethod(methodName);
        return (string) theMethod.Invoke(instance, new[] { input });
    }

    public void Dispose()
    {
        assemblyLoadContext.Unload();
        assemblyLoadContext = null;
        bytes = null;
        assembly = null;
    }
}

И тестовый код:

    var allowedAssemblies = new[] { "System", "System.Linq", "System.Linq.Expressions" };
    var allowedTypes = new Type[] { typeof(object) };
    string result;

    using (var loader = new PluginLoader())
    {
        loader.Load("MyCustomPlugin", code, allowedAssemblies, allowedTypes);
        result= loader.Run("HelloWorldPlugin", "GetResult", "World!");
    }

    Console.WriteLine(result);
    Console.ReadLine();

Я знаю, что этот пользователь может иметь доступ к вводу-выводу, сети,... которые представляют собой огромные угрозы. Я попытался использовать System.IO.Directory.GetCurrentDirectory (): поскольку я не добавил сборку System.IO в allowedAssemblies, это вызывает исключение в разделе компиляции. Я также попытался получить текущую личность пользователя и несколько базовых работ с отражением, и все они вызывают исключение.

Если я ограничиваю разрешенные ссылки до компиляции, как пользователь может выполнить опасный код для доступа к ресурсам? Каковы угрозы, кроме выполнения непрерывного цикла (while True loop)?

0 ответов

Другие вопросы по тегам