# [CodeBlog]
Restricted AppDomain example - by simon at Wed, 25 Feb 2009 23:28:30 GMT
Just a quick example:-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Policy;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Reflection;
using System.IO;
namespace RestrictedAppDomainTest
{
class Program
{
/// <summary>
/// Example program demonstrating AppDomains with restrictive security
/// Note that it requires the existance of C:\windows\win.ini to actually demonstrate it, but you
/// can modify this to any other file.
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
//we want to define a level of access for this appdomain to have
PolicyLevel levelOfAccess = PolicyLevel.CreateAppDomainLevel();
//now we grant the permissions to do something specific:-
PermissionSet executeOnly = new PermissionSet(PermissionState.None);
//bare minimum to run at all
executeOnly.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
//if you wanted to grant the rights to read files then you need to grant FileIO:-
//uncommenting this means that the appdomain created can complete its task rather than erroring
//as intended:-
// executeOnly.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, "C:\\Windows\\"));
PolicyStatement executeOnlyStatement = new PolicyStatement(executeOnly);
UnionCodeGroup applicablePolicy = new UnionCodeGroup(new AllMembershipCondition(),
executeOnlyStatement);
//and tie the code group we defined to the level of access
levelOfAccess.RootCodeGroup = applicablePolicy;
//now we could add rights for things we trust, so they can assert that they
//want to perform operations that the appdomain normally can't:-
/*
* This is commented out because it grants the running assembly those rights, but this is an
* example of how to do it:-
*
* After using this, you can use a MessageBox or form from inside the plugin.
*
* (Change to a using multiple assemblies to restrict each one seperately)
*
//this example results in the UI being available
PermissionSet displayUI = new PermissionSet(PermissionState.None);
displayUI.AddPermission(new UIPermission(PermissionState.Unrestricted));
//wrap the permission set in a statement
PolicyStatement displayUIPolicyStatement = new PolicyStatement(displayUI);
//And only grant this permission when the assembly has been strong named
AssemblyName exampleAssembly = Assembly.GetExecutingAssembly().GetName();
UnionCodeGroup selectPolicy = new UnionCodeGroup(new StrongNameMembershipCondition(
new StrongNamePublicKeyBlob(exampleAssembly.GetPublicKey()
), exampleAssembly.Name, exampleAssembly.Version
), displayUIPolicyStatement);
//and finally we add this new policy to the previous one so there's a chain
applicablePolicy.AddChild(selectPolicy);
*/
//create the appdomain with our basic permission set!
AppDomain domain = AppDomain.CreateDomain("RestrictedDomain", null,
AppDomain.CurrentDomain.SetupInformation); //do not supply the level permission using this
// constructor, you can't change it later using//SetAppDomainPolicy
//define the total security policy here
domain.SetAppDomainPolicy(levelOfAccess);
//now we load our example class from below, for this example we are using the currently executing
//assemblies name this can be replaced with another filename, or full assembly name to load a
//particular one from the GAC for example
string thisAssemblyName = Assembly.GetExecutingAssembly().GetName().Name;
IPlugin examplePlugin = (IPlugin)domain.CreateInstanceAndUnwrap(thisAssemblyName,
"RestrictedAppDomainTest.ExampleClass");
//this starts running a thread and doing other things that are potentially dodgy.
examplePlugin.DoSomething();
//(note that if this didn't choose to start a thread it would still run in a seperate thread anyway)
//no (security) exception here, just to show we are unaffected by the appdomain's restrictions!
string dummyData = File.ReadAllText("C:\\windows\\win.ini");
Console.WriteLine("An app domain is now started and running in the background.");
Console.WriteLine();
Console.WriteLine("Press any key to terminate and unload the restricted appdomain!");
Console.ReadKey();
//This results in the termination of the thread the AppDomain//started, and unloading of
//any resources (including locked files or assemblies).
AppDomain.Unload(domain);
Console.WriteLine("Domain has been unloaded. Press any key to end.");
Console.ReadKey();
}
}
/// <summary>
/// Defines an example plugin
/// </summary>
public interface IPlugin
{
void DoSomething();
}
/// <summary>
/// An example (malicious) plugin
/// </summary>
public class ExampleClass : MarshalByRefObject, IPlugin
{
/// <summary>
/// This is called from the unrestricted AppDomain
/// </summary>
public void DoSomething()
{
voidDelegate startDoingThings = new voidDelegate(longNaughtyOperation);
//run the method on a different thread to demonstrate we can //even start threads here
startDoingThings.BeginInvoke(null, null);
}
private delegate void voidDelegate();
private void longNaughtyOperation()
{
while (true)
{
try
{
//this is denied so will fail
string dummyData = File.ReadAllText("C:\\windows\\win.ini");
//this won't ever happen hopefully :)
Console.WriteLine("Restricted AppDomain completed its work!!!");
//stop looping if the above works!
break;
}
catch (SecurityException)
{
Console.WriteLine("Security exception as expected, trying again so you can terminate this thread... :)");
}
Thread.Sleep(1000);
}
}
}
}
Permalink (
0 Comments)