- Introduction
- Security Policy and Assemblies
- Evidence-Based Security Policy
- Determining Security Policy
- Administering Security Policy
- Principle of Least Privilege
Evidence-Based Security Policy
How does the Common Language Runtime (CLR) decide which permissions to grant and which to deny? Code access security is also known by another name: evidence-based security. The CLR examines the evidence associated with the code to determine which security policy group the code belongs to. The CLR then checks what permission set is associated with that code group. (Permission sets and code groups are described later in this article.) If the code group has the permissions demanded, the request is granted; if not, an exception is thrown.
Evidence
To understand security policy, you first have to understand what evidence is. As mentioned earlier, evidence is used to authenticate the code. As such there are several identity permissions that are used to identify code:
PublisherIdentityPermission models the software publisher's digital signature. This answers the question: Who published the assembly?
SiteIdentityPermission models the web site where code originated. This answers the question: From what web site did the assembly come?
StrongNameIdentityPermission models the strong name of an assembly. This answers the question: What is the name of this assembly?
ZoneIdentityPermission models the zone where the code originated, corresponding to the Internet Explorer zones: Local intranet, Trusted sites, Internet, Restricted, and MyComputer. This answers the question: From what zone did the assembly come?
URLIdentityPermission models the URL and the protocol where the code originated. The entire URL, including the protocol and the filename, is part of the identity. This answers the question: From what URL did the assembly come?
You can examine the evidence associated with an assembly. The evidence collection associated with an assembly can be obtained from the evidence enumerator.
The following example writes out the evidence associated with a strongly named assembly:
Evidence ev = AppDomain.CurrentDomain.Evidence; IEnumerator iEnum = ev.GetEnumerator(); bool bNext; Console.WriteLine("Evidence Enumerator has {0} members", ev.Count); bNext = iEnum.MoveNext(); while (bNext == true) { object x = iEnum.Current; Type t = x.GetType(); Console.WriteLine(t.ToString()); if (t == typeof(System.Security.Policy.Site)) { Site site = x as Site; Console.WriteLine(" " + site.Name); } else if (t == typeof(System.Security.Policy.Zone)) { Zone zone = x as Zone; Console.WriteLine(" " + zone.SecurityZone.ToString()); } else if (t == typeof(System.Security.Policy.Url)) { Url url = x as Url; Console.WriteLine(" " + url.Value.ToString()); } else if (t == typeof(System.Security.Policy.Hash)) { Hash hash = x as Hash; byte[] md5Hash = hash.MD5; byte[] sha1Hash = hash.SHA1; Console.WriteLine(" MD5 Hash of Assembly:"); Console.Write(" "); for(int i = 0; i < md5Hash.Length; i++) Console.Write(md5Hash[i]); Console.WriteLine(); Console.WriteLine(" SHA1 Hash of Assembly:"); Console.Write(" "); for(int i = 0; i < sha1Hash.Length; i++) Console.Write(sha1Hash[i]); Console.WriteLine(); } else if (t == typeof(System.Security.Policy.StrongName)) { StrongName sn = x as StrongName; Console.WriteLine(" StrongName of Assembly is: {0} version: {1}", sn.Name, sn.Version); Console.WriteLine(" Assembly public key:"); Console.Write(" "); Console.WriteLine(sn.PublicKey.ToString()); } bNext = iEnum.MoveNext(); }
NOTE
As the code example makes clear, evidence is really associated with individual application domains. Hosts can change the evidence associated with an application domain.
Although they derive from CodeAccessPermission, these are not code access permission classes. Evidence is extensible. You can define your own types of evidence.
Code Groups and Permission Sets
Code identity permissions are used to define a security policy code group. For example, all code whose ZoneIdentityPermission is MyComputer belongs to the predefined MyComputerZone code group. A permission set is a named set of permissions that can be associated with a code group. Administrators specify which code groups and permission sets are defined for their system. By determining which code group an assembly belongs to, the CLR can determine which permissions are allowed or denied to an assembly. More than one code group can be associated with a permission set.
There are several built-in permission sets:
Nothing: No permissions (cannot run).
Execution: Permission to run, but no permissions that allow use of protected resources.
Internet: The default policy permission set suitable for content of unknown origin.
LocalIntranet: The default policy permission set for within an enterprise.
Everything: All standard (built-in) permissions except permission to skip verification. This is the only built-in permission set that can be modified.
FullTrust: Full access to all resources protected by permissions that can be unrestricted.