Resources

Application Domains in the .NET framework

Application domains enable calling of external assemblies with optimal efficiency and security.

Services are assemblies that run in background, presenting no UI and controlled by specialised tools.

Lesson 1: Creating Application Domains

Application Domain = logical container allowing multiple assemblies to reside in one process, but prevents them from accessing each others memory. Offer many of the features of a process such as separate memory spaces and access to resources. More efficient than separate processes as there is not the overhead of launching separate processes.

.NET manages application domains, OS manages processes.

IIS ASP.NET worker process = example of application domain. If 10 people visit site simultaneously then 10 separate application domains are created (one for each user) within Aspnet_wp.exe to run 10 separate instances of the assembly.

Each instance of the assembly can store property called userName without concern that other instances will be able to access or overwrite the contents of the property. Same effect could be achieved by launching 10 separate processes, but this would be expensive in terms of start up and switching times.

Usually rely on run-time hosts (e.g. ASP.NET, Internet Explorer, the OS) to create application domains for assemblies. Use friendly tools such as IIS Manager and .NET Framework Configuration tool to control them.

Can create own application domains to isolate multiples instances of an assembly. Besides providing enhanced security also offers:

AppDomain Class

To use an application domain create instance of AppDomain class using one of the overloaded CreateDomain methods, e.g.

AppDomain d = AppDomain.Create("NewDomain");

Then call ExecuteAssembly to launch the assembly,

d.ExecuteAssembly("Assembly.exe");

To unload call the static Unload method.

AppDomain.Unload(d);

Lesson 2: Configuring Application Domains

Restricting permissions of application domain greatly reduces risk that assembly will cause malicious action, e.g. Purchase 3

rd party application to communicate with database. Attacker discovers vulnerability in this assembly and uses it to configure a spyware application to start automatically. To the user the security vulnerability appears to be your applications fault.

The same scenario with limited privileges: the attacker discovers the vulnerability in the 3

rd party assembly. When the attacker exploits the vulnerability to write files to the local hard drive, the file I/O is rejected because of insufficient privileges. While the vulnerability still exists, the limited privileges granted to the application domain prevented it from being exploited.

Above is an example of "defence-in-depth" - principal of providing multiple levels of protection so that still protected in event of vulnerability.

Providing Host Evidence For Assembly

When creating application domain and launching assemblies you have complete control over evidence. Evidence = information that runtime gather about assembly to determine what code groups it belongs to. These determine its privileges. Common forms of evidence = folder or website assembly is running from and digital signatures.

To provide evidence for assembly create a System.Security.Policy.Evidence object. Pass this as parameter to the overloaded ExecuteAssembly method. The constructor requires two object arrays one represents the host evidence, the other the assembly. Either can be null, usually only assign to the host evidence array.

Simplest way to control permissions assigned to assembly in an application domain is to pass Zone evidence, e.g.

object[] hostEvidence = {new Zone(SecurityZone.Internet)};

Evidence internetEvidence = new Evidence(hostEvidence, null);

AppDomain myDomain = AppDomain.CreateDomain("MyDomain");

myDomain.ExecuteAssembly("SecondAssembly.exe", internetEvidence);

Will result in application domain with the permission set granted to the Internet_Zone group (extremely restrictive).

Providing Host Evidence For Application Domain

Similar to providing evidence for new assembly. Uses overloaded AppDomain.CreateDomain

...

object[] hostEvidence = {new Zone(SecurityZone.Internet)};

Evidence appDomainEvidence = new Evidence(hostEvidence, null);

AppDomain myDomain = AppDomain.CreateDomain("MyDomain", appDomainEvidence);

myDomain.ExecuteAssembly("SecondAssembly.exe");

Configuring Application Domain Properties

Can use AppDomainSetup class to configure way the CLR creates application domains. Most important property is ApplicationBase that controls the root directory of the application. Other arguments used to configure a particular application domain. Changing properties of AppDomainSetup does not affect existing AppDomains, only new ones created by AppDomain.CreateDomain. To apply properties to application domain, create and configure AppDomainSetup object and pass to AppDomain.CreateDomain method, e.g.

AppDomainSetup ads = new AppDomainSetup();

ads.ApplicationBase = "file://" + System.Environment.CurrentDirectory;

ads.DisallowCodeDownload = true;

AppDomain d = AppDomain.CreateDomain("New Domain", null, ads);

Lesson 3: Creating Windows Services

What is a service?

Processes that run in background without UI and in their own session. Can be automatically started when computer starts (even without user logging on). Ideal for applications that should execute constantly and do not require user interaction. Differences to other project types:

Implementing Service

After creating services project:

  1. In designer properties modify ServiceBase.ServiceName property. Every service must have unique name very important to change this setting. This is not the friendly name seen in service snap-in, instead it is used by OS to identify service and for use by command line tools.
  2. Add code to OnStart to set-up polling / monitoring the service requires. OnStart does not perform the monitoring. It must return to the OS once the service has started. It must not loop or block.
  3. Add code to OnStop to perform the action required to stop the service.
  4. Optionally override OnPause, OnContinue and OnShutdown.

Downloads