Welcome to MSDN Blogs Sign in | Join | Help

An Enhanced Version of the Sandboxed AppDomain

Last week I showed how to create an AppDomain with a limited set of permissions.  I also presented an easy way to create a StrongNameMembershipCondition.  Now I'll put the two together to make an enhanced version of the sandboxed AppDomain.

Why create a new version?   The version I presented last time works wonderfully if you're going to create the AppDomain and then call AppDomain.ExecuteAssembly to run the untrusted code in it.  However, especially in plugin scenarios, a more common approach is to create a MarshalByRefObject in your application that you load into the new AppDomain, and then have this proxy object invoke the untrusted assembly.  This scenario won't work with the last version of CreateRestrictedDomain, since all code loaded into the AppDomain will be granted the same limited set of permissions.

This can be easily rectified by modifying CreateRestrictedDomain to take a second parameter, which is an extra code group to add to the policy:

/// <summary>
/// Create an AppDomain that contains policy restricting code to execute
/// with only the permissions granted by a named permission set
/// </summary>
/// <param name="permissionSetName">name of the permission set to restrict to</param>
/// <param name="extraCodeGroup">extra code groups to add</param>
/// <exception cref="ArgumentNullException">
/// if <paramref name="permissionSetName"/> is null
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// if <paramref name="permissionSetName"/> is empty
/// </exception>
/// <returns>AppDomain with a restricted security policy</returns>
public static AppDomain CreateRestrictedDomain(string permissionSetName, CodeGroup extraCodeGroup)
{
    if(permissionSetName == null)
        throw new ArgumentNullException("permissionSetName");
    if(permissionSetName.Length == 0)
        throw new ArgumentOutOfRangeException("permissionSetName", permissionSetName, "Cannot have an empty permission set name");
        
    // Default to all code getting nothing
    PolicyStatement emptyPolicy = new PolicyStatement(new PermissionSet(PermissionState.None));
    UnionCodeGroup policyRoot = new UnionCodeGroup(new AllMembershipCondition(), emptyPolicy);

    // Grant all code the named permission set passed in
    PolicyStatement permissions = new PolicyStatement(GetNamedPermissionSet(permissionSetName));
    policyRoot.AddChild(new UnionCodeGroup(new AllMembershipCondition(), permissions));
        
    // add the extra code groups to the tree
    if(extraCodeGroup != null)
        policyRoot.AddChild(extraCodeGroup);
        
    // create an AppDomain policy level for the policy tree
    PolicyLevel appDomainLevel = PolicyLevel.CreateAppDomainLevel();
    appDomainLevel.RootCodeGroup = policyRoot;

    // create an AppDomain where this policy will be in effect
    string domainName = String.Format("Restricted Domain: {0}", permissionSetName)
    AppDomain restrictedDomain = AppDomain.CreateDomain(domainName);
    restrictedDomain.SetAppDomainPolicy(appDomainLevel);

    return restrictedDomain;
}

Now, in order to enable the MarshalByRefObject scenario, we just need to make a code group that grants FullTrust to the assembly that's creating the AppDomain.  This is easily done with the CreateStrongMembershipCondition method:

// create a code group that gives this assembly full trust
PolicyStatement fullTrust = new PolicyStatement(new PermissionSet(PermissionState.Unrestricted));
CodeGroup trustSelf = new UnionCodeGroup(CreateStrongNameMembershipCondition(), fullTrust);        
        
AppDomain restrictedDomain = CreateRestrictedDomain("Internet", trustSelf);

Using the above snippet creates an AppDomain policy similar to:

  • AllCode: Nothing
    • All Code: Internet
    • AppStrongName: FullTrust

As you can see, this policy will grant Internet permissions to all code in the AppDomain except for the assembly that created the domain, which will remain fully trusted.
Published Tuesday, November 02, 2004 11:52 AM by shawnfa
Filed under: , ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Secure AppDomain example

Tuesday, November 02, 2004 5:09 PM by Robert Hurlbut's .NET Blog

# re: An Enhanced Version of the Sandboxed AppDomain

Wednesday, November 03, 2004 4:55 AM by Kevin Westhead
Thanks for the sample. I have applied a slightly different approach myself where, instead of specifying a CodeGroup I use a speparate method to add StrongNames (or StrongNameMembershipConditions) for fully trusted assemblies. I then call PolicyLevel.AddFullTrustAssembly for each of them before creating the AppDomain. I guess the advantage of this approach is that it allows greater flexibility per assembly, e.g. you might want another assembly to run under LocalIntranet instead of Internet or FullTrust.

# Secure AppDomain example

Wednesday, November 03, 2004 10:42 AM by Robert Hurlbut's .NET Blog

# re: An Enhanced Version of the Sandboxed AppDomain

Wednesday, November 03, 2004 9:32 AM by Shawn
Hi Kevin,

I've actually been planning a post on what that full trust list means, its for a different purpose than what you've been using it for. To accomplish what you're trying to do I would write a method that got a strnong name membership condition fore each assembly and matched them to the correct permission set. Then make all of those code groups children of a big union code group that granted all code nothing.

-Shawn

# re: An Enhanced Version of the Sandboxed AppDomain

Thursday, November 04, 2004 3:28 PM by Kevin Westhead
Thanks for the extra info Shawn. I look forward to your posts about evidence and full trust.

# re: An Enhanced Version of the Sandboxed AppDomain

Friday, November 05, 2004 5:06 PM by Jonathan de Halleux
Bookmarked...

# re: An Enhanced Version of the Sandboxed AppDomain

Sunday, November 07, 2004 11:40 AM by LF
FullTrustAssemblies are those that implement CAS permissions. I think they are not evaluated by CAS at all. While it will work and I used it myself at first. It sounds wrong.

# Creating a partially-trusted AppDomain

Sunday, November 07, 2004 6:39 PM by Office Development, Security, Randomness...

# Partially-Trusted AppDomains

Sunday, November 07, 2004 9:09 PM by Robert Hurlbut's .NET Blog

# Peter Torr Provides More Details on Sandboxing AppDomains

Monday, November 08, 2004 12:30 PM by .Net Security Blog

# Partially-Trusted AppDomains part 2

Tuesday, November 09, 2004 8:15 AM by Robert Hurlbut's .NET Blog

# New and Notable 66

Saturday, November 20, 2004 12:12 PM by Sam Gentile's Blog

# New and Notable 66

Saturday, November 20, 2004 12:13 PM by Sam Gentile's Blog

# Creare un AppDomain con restrizioni sui permessi

Tuesday, November 23, 2004 7:39 PM by Il Blog di Paolo Pialorsi

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker