3

I want to run some of my code in Python. However, for security reasons i need to run it in some kind of sandbox. What I'm doing is: First i create a domain with restricted permissions:

private AppDomain CreateDomain()
    {
        AppDomainSetup setup = new AppDomainSetup();
        Assembly thisAssembly = Assembly.GetExecutingAssembly();
        setup.ApplicationBase = Path.GetDirectoryName(thisAssembly.Location);

        AssemblyName name = typeof(Program).Assembly.GetName();

        StrongName sn = new StrongName(new StrongNamePublicKeyBlob(name.GetPublicKey()), name.Name, name.Version);

        PermissionSet permSet = new PermissionSet(PermissionState.None);
        permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));


        setup.PartialTrustVisibleAssemblies = new[] { sn.Name + ", PublicKey=" + sn.PublicKey.ToString() };

        AppDomain domain = AppDomain.CreateDomain(
            "Sandbox",
            AppDomain.CurrentDomain.Evidence,
            setup,
            permSet,
            sn);

        return domain;
    }

Next i create python engine and other needed items(d is a Dictionary which im working on in python:

string pythonCode = File.ReadAllText(@"D:\Python\Class.py");
string createInstanceCode = "ObjectNew = Class(dictionary)";

ScriptEngine pyEngine = IronPython.Hosting.Python.CreateEngine(domain);
ScriptScope pyScope = pyEngine.CreateScope();
pyScope.SetVariable("dictionary", d);

pyEngine.Execute(pythonCode, pyScope);
pyEngine.Execute(createInstanceCode, pyScope);

The python code is just one big class with functions in it. I want to call these functions from C# and get the results so i try to create an instance of that class. Using advice from this question: How do I call a specific Method from a Python Script in C#? I am doing this:

var testObject = pyScope.GetVariable("ObjectNew");

This is the error i get at this point: An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in PythonTimeTests.exe

This doesn't happen if i change this

ScriptEngine pyEngine = IronPython.Hosting.Python.CreateEngine(domain);

to

ScriptEngine pyEngine = IronPython.Hosting.Python.CreateEngine();

But then i can't manage the permissions IronPython has. Is there a way of doing this differently without serialization, perhaps using reflection? Or is there a better way of sandboxing it(maybe sandbox the whole C# code that manages IronPython)?

Community
  • 1
  • 1
Kuczi
  • 357
  • 4
  • 18

0 Answers0