David Hauck
David Hauck

Reputation: 269

AppDomain in Azure Function

I have tried to create an AppDomain within Azure Functions to run untrusted code. Creating the domain seems to work fine, but when I try to load in assemblies, it seems like they get loaded in incorrectly.

First I tried a simple AppDomain:

public class Sandboxer
{
    public void Run()
    {
        AppDomain newDomain = AppDomain.CreateDomain("name");
        var obj = newDomain.CreateInstance(typeof(OtherProgram).Assembly.FullName, typeof(OtherProgram).FullName).Unwrap();
    }
}

public class OtherProgram : MarshalByRefObject
{
    public void Main(string[] args)
    {
        Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
        foreach (var item in args)
            Console.WriteLine(item);
    }
}

I got an error

"System.IO.FileNotFoundException : Could not load file or assembly 'Sandboxer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2cd9cb1d6fdb50b4' or one of its dependencies. The system cannot find the file specified."

I then tried to set the appliactionBase to the folder with my dll in it.

public class Sandboxer
{
    public void Run()
    {
        var location = typeof(OtherProgram).Assembly.Location;
        AppDomainSetup ads = new AppDomainSetup();
        ads.ApplicationBase = Path.GetDirectoryName(location);
        AppDomain newDomain = AppDomain.CreateDomain("name", null, ads);
        var obj = newDomain.CreateInstance(typeof(OtherProgram).Assembly.FullName, typeof(OtherProgram).FullName).Unwrap();
        var other = obj as OtherProgram;
        var other2 = obj as MarshalByRefObject;
    }
}

public class OtherProgram : MarshalByRefObject
{
    public void Main(string[] args)
    {
        Console.WriteLine(AppDomain.CurrentDomain.FriendlyName);
        foreach (var item in args)
            Console.WriteLine(item);
    }
}

In this case, "other" is null at the end of the Run() method, but "other2" is a __TransparentProxy. It seems like it is finding and loading the dll, but doesn't understand the type.

How can I fix this problem? Thanks!

Cross posted here: https://social.msdn.microsoft.com/Forums/azure/en-US/59b119d8-1e51-4460-bf86-01b96ed55b12/how-can-i-create-an-appdomain-in-azure-functions?forum=AzureFunctions&prof=required

Upvotes: 0

Views: 1680

Answers (3)

David Hauck
David Hauck

Reputation: 269

AppDomains are not usable with Azure Functions. In order to properly sandbox code in Azure Functions, you would have to create a new Azure Functions App and run the code there.

If you are allowing users to write scripts, you can use another language like Lua that allows easy sandboxing.

Upvotes: 0

Bruce Chen
Bruce Chen

Reputation: 18465

In this case, "other" is null at the end of the Run() method, but "other2" is a __TransparentProxy. It seems like it is finding and loading the dll, but doesn't understand the type.

According to your description, I could encounter the similar issue, I tried to create a Console application to check this issue and found that the code could work as expected under a Console application.

For Azure Function, obj as OtherProgram always returns null. Then I tried to instantiate OtherProgram under the current domain as follows:

var obj=AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap(typeof(OtherProgram).Assembly.Location, typeof(OtherProgram).FullName);
OtherProgram op = obj as OtherProgram;
if (op != null)
    op.PrintDomain(log);

The above code could work as expected, but I did not found why the object under a new AppDomain always returns null. You may try to add a issue under Azure/Azure-Functions.

Upvotes: 1

Simon Luckenuik
Simon Luckenuik

Reputation: 355

This is how I would do it in a conventional .NET application, should work in Azure Functions:

  1. Register to the AppDomain.AssemblyResolve event on the newly created AppDomain
  2. In the event handler, resolve the assembly path using the Function Directory / Function App Directory in order to point to the bin folder

Upvotes: 0

Related Questions