Security Permissions

Security Permissions

Security permissions define the kinds of activities the code requests (or demands, or denies, and so on) the right to perform. The same permissions are used in security policy definitions, specifying what sort of applications have the right to perform these activities and under what circumstances.

These permissions are represented by special classes of the .NET Framework class library. Each permission class is accompanied by a permission attribute class, a class whose instance constructor is used as a type of security custom attribute. Applying a security custom attribute to a metadata item leads to instantiation of the security object targeting the associated metadata item.

In some sense, it’s easier to describe the permissions in terms of the accompanying attribute classes, because the permission classes have instance constructors of different signatures, whereas the instance constructors of the security attribute classes invariably have one parameter—the security action code—and all the parameters of the instance constructor(s) of the respective permission class are represented by the attribute’s properties, set through name/value pairs.

The permissions form three groups. The first group includes the permissions related to access rights to certain resources. The second group consists of permissions related to identity characteristics of the code, including its origin. The third group represents custom permissions, invented by .NET Framework users for their particular purposes. It seems to be a general principle of the .NET Framework that if you can’t find something satisfactory within the Framework, it at least provides you with the means to build your own better mousetrap.

Because most of the permission classes belong to the namespace System.Security.Permissions, of the Mscorlib.dll assembly, I’ve specified the assembly and namespace in the following sections only when they are different.

Access Permissions

The access permissions control access rights to various resources. The group includes the following nine permissions:

  • [System.DirectoryServices]System.DirectoryServices. DirectoryServicesPermission  This permission defines access to the Active Directory. The attribute class has two properties:

    • Path (type string) indicates the path for which the permission is specified.

    • PermissionAccess (type int32) specifies the type of access: a value of 0 indicates no access, a value of 2 indicates browse access, and a value of 6 indicates write access.

  • [System]System.Net.DnsPermission  This permission defines the right to use the Domain Name Services (DNS). The attribute class has no properties because there are no details to specify: either you can use DNS or you can’t.

  • EnvironmentPermission  This permission defines the right to access the environment variables. The attribute class has three properties, all of type string, which specify the names of the environment variables affected:

    • All specifies the name of the environment variable that can be accessed in any way.

    • Read specifies the name of the environment variable that can be read.

    • Write specifies the name of the environment variable that can be written to.

  • FileDialogPermission  This permission defines the right to access a file selected through the standard Open or Save As dialog. The attribute class has two properties, both of type bool, for which true indicates that the access is to be granted and false indicates that it is to be denied:

    • Open grants or denies the right to read the file.

    • Save grants or denies the right to write to the file.

  • FileIOPermission  This permission defines the right to access specified directories or individual files. The attribute class has five properties, all of type string, which contain a path or a full-path file specification. If the path is specified, the permission is propagated to the whole directory subtree starting at this path. The attribute class properties are as follows:

    • All indicates full access to the specified path or file.

    • Read indicates read access to the specified path or file.

    • Write indicates write access, including file overwriting and new file creation.

    • Append indicates append access—in other words, the existing file can be appended but not overwritten, and a new file can be created.

    • PathDiscovery indicates browse access—for example, querying the current directory, getting a filename back from the file dialog, and so on.

  • IsolatedStorageFilePermission  This permission defines the right to access the isolated storage. Briefly, the isolated storage is a storage space allocated specifically for the user’s application, providing a configurationless data store independent of the structure of the local file system. Data compartments within the isolated storage are defined by the identity of the application or component code. Thus, there’s no need to work magic with the file paths to ensure that the data storages specific to different applications don’t overlap. The attribute class has two properties:

    • UsageAllowed (int32-based enumeration IsolatedStorageContainment) indicates the isolated storage type.

    • UserQuota (type int64) indicates the maximum size in bytes of the isolated storage that can be allocated for one user.

      The UsageAllowed property can be assigned the following int32 values:

None (0x00)

DomainIsolationByUser (0x10)

AssemblyIsolationByUser (0x20)

DomainIsolationByRoamingUser (0x50)

AssemblyIsolationByRoamingUser (0x60)

AdministerIsolatedStorageByUser (0x70)

UnrestrictedIsolatedStorage (0xF0)

  • ReflectionPermission  This permission defines the right to invoke Reflection methods on nonpublic class members and to create dynamic assemblies at run time using the methods of Reflection.Emit. The attribute class has four properties:

    • MemberAccess (type bool) grants or denies the right to access the nonpublic members through Reflection methods.

    • TypeInformation (type bool) grants or denies the right to invoke Reflection methods to retrieve information about the class, including information about the nonpublic members.

    • ReflectionEmit (type bool) grants or denies the right to invoke Reflection.Emit methods.

    • Flags (int32-based enumeration ReflectionPermissionFlag) summarizes the three preceding properties, using a binary OR combination of flags 0x01 for TypeInformation, 0x02 for MemberAccess, and 0x04 for ReflectionEmit.

  • RegistryPermission  This permission defines the right to manipulate the registry keys and values. This permission is analogous in all ways to FileIOPermission except that it specifies the access rights to the registry rather than to the file system. The attribute class has four properties, all of type string, which contain the registry path:

    • Create grants the right to create the keys and values anywhere in the registry subtree, starting with the node specified in the property.

    • Read grants the right to read the keys and values.

    • Write grants the right to change the existing keys and values.

    • All grants all of the three preceding rights.

  • SecurityPermission  This permission defines a set of 13 essential rights to modify the behavior of the common language runtime security subsystem itself. The attribute class has 13 properties of type bool (one for each right) plus one property (int32-based enumeration SecurityPermissionFlag) representing an OR combination of binary flags corresponding to the Boolean properties:

    • Assertion defines the right to override a security check for any granted permission. The respective binary flag is 0x0001.

    • UnmanagedCode defines the right to invoke the native unmanaged code, for example, through P/Invoke or COM interoperation (flag 0x0002). If this right is granted, it is asserted every time the unmanaged code is invoked, which results in a significant performance hit. To avoid this, the custom attribute System.Security.SuppressUnmanagedCodeSecurityAttribute can be used. The presence of this attribute suppresses the repetitive security checks when the unmanaged code is invoked.

    • SkipVerification defines the right to run the code without the IL verification procedures at JIT compilation time (flag 0x0004). This is an extremely dangerous right. To avoid inviting trouble, this right should be granted only to code that is known to be safe and that comes from a trusted source.

    • Execution defines the right to run the code (flag 0x0008). This right, which is granted to almost any code, is the opposite of SkipVerification. The right can be revoked by the administrator or by user security policies regarding specific applications or specific sources that are known for or suspected of being the purveyors of malicious code.

    • ControlThread defines the right to perform thread control operations, such as suspending, interrupting, stopping a thread, changing the thread priority, and so on (flag 0x0010).

    • ControlEvidence defines the right of the domain host to give evidence to the applications loaded in the domains created by this host (flag 0x0020). The evidence in question usually includes information about the origin and strong name signature of the loaded assembly. If the domain host does not have this right, it gives its own evidence instead.

    • ControlPolicy defines the right to access and modify security policies, both user-specific and machinewide (flag 0x0040). This is another extremely dangerous right that must be granted with great caution.

    • SerializationFormatter defines the right to perform the serialization formatting operations and to retrieve and change the characteristics of any nontransient members of the serializable types, regardless of the accessibility of these members (flag 0x0080). This permission resembles ReflectionPermission in the sense that both are of very low opinion about the accessibility rules and allow you to access and invoke private class members at will.

    • ControlDomainPolicy defines the right of the domain host to specify domainwide security policy (flag 0x0100).

    • ControlPrincipal defines the right to replace the Principal object (carrying the user’s identity characteristics) for a given thread, for example, in order to implement role-based security (flag 0x0200). In the role-based security model, the security actions depend on the identity (Principal object) of the “code runner” and the role in which the “code runner” operates.

    • ControlAppDomain defines the right to create and manipulate the application domains (flag 0x0400).

    • RemotingConfiguration defines the right to configure the remoting types and channels (flag 0x0800).

    • Infrastructure defines the right to plug the code into the common language runtime infrastructure, such as adding remoting context sinks, envoy sinks, and dynamic sinks (flag 0x1000).

    • Flags is a summary binary representation of the 13 rights just listed. The validity mask is 0x1FFF.

Identity Permissions

The access permissions describe the resources to be accessed and the actions to be performed. The identity permissions describe the identities of the agents who are accessing these resources and performing these actions. As a trivial example, suppose that you’ve created a method or a component so atrocious that you want only components written by your company to be able to access it, because you can’t trust anyone else to keep the beast in check.

It’s a good practice to use identity permissions to extend rather than limit the rights granted to the code of a specific origin. Limiting the rights on the basis of the code’s identity is a poor protection technique because the identity information of the code can easily be suppressed. A software publisher you particularly dislike can simply neglect to sign its malicious software, for instance, and you’ll never know that this particular code must be treated with extra caution. Or the obnoxious snooping marketing site you’d love to block can start operating through a different Web server or spoof its IP address.

The five identity permissions all belong to the namespace System.Security.Permissions and are defined in the Mscorlib.dll assembly:

  • ZoneIdentityPermission  This permission identifies the zone from which the calling code originates. The zones are defined and mapped from the URLs by APIs of IInternetSecurityManager and related interfaces. The zones are not overlapping, and any particular URL can belong to only one zone. The attribute class has one property, Zone (int32-based enumeration [mscorlib]System.Security.SecurityZone). The values of the enumeration are as follows:

    • MyComputer (0x0) means that the application is run from the local drive.

    • Intranet (0x1) means that the application is run from a closed intranet.

    • Trusted (0x2) means that the application is run from a trusted server.

    • Internet (0x3) means that the application originates from the Internet.

    • Untrusted (0x4) means that the application’s origin is suspicious and that a high level of security is required.

    • NoZone (0xFFFFFFFF) means that no zone information is available.

  • StrongNameIdentityPermission  This permission identifies an assembly by its strong name attributes—namely, by the assembly name, the assembly version, and the public encryption key. The public encryption key of the assembly must exactly match the one specified in the permission.

    The assembly name, however, might only partially match the one specified in the permission because a wildcard character (*) can be used in the assembly name specification in the permission. The name of the assembly is usually a dotted name, such as System.DirectoryServices, and any right part of the name can be replaced with the wildcard character. Thus, System.DirectoryServices denotes this specific assembly only, System.* denotes any assembly whose name starts with System. (including the assembly System), and * denotes any assembly. If, for example, the permission includes the Microsoft private encryption key and the assembly name is given as System.DirectoryServices, the permission identifies the assembly System.DirectoryServices from the .NET Framework. If the assembly name included is System.*, the permission identifies it as any Microsoft assembly whose name begins with System. If the assembly name is given simply as *, the permission identifies it as any assembly produced and signed by Microsoft. It is illegal to replace the left part of the name with the wildcard character (for example, *.DirectoryServices).

    The assembly version includes four components: the major version, the minor version, the build number, and the revision number. The fourth or both the third and the fourth components can be omitted, but the first two components must be specified, unless the version is not specified at all. The attribute class has three properties, all of type string:

    • Name is the name of the assembly, possibly with a wildcard character in the right part.

    • PublicKey is the encoded hexadecimal representation of the public encryption key.

    • Version is the literal representation of the version—for example, 1.12.123.1 or 1.12.

  • PublisherIdentityPermission  This permission specifies the software publisher’s identity, based on the public key defined by an X509v3 certificate. This certificate is issued by a trusted certification authority and contains encrypted information authenticating the publisher’s public encryption key. The name of the publisher is ignored. The associated attribute class has three properties, all of type string. Only one of the properties can be set, because they represent alternate ways of obtaining the certificate:

    • X509Certificate contains the explicit X509v3 certificate in a coded form.

    • CertFile contains the name of the file containing the certificate.

    • SignedFile contains the name of the file strong name signed with this certificate, so that the certificate can be obtained from the file’s strong name signature.

  • SiteIdentityPermission  This permission identifies the Web site from which the code originates. The attribute class has one property, Site, of type string, which contains part of the Web site’s URL with a stripped protocol specification at the start and the filename at the end—for example, www.microsoft.com in the URL http://www.microsoft.com/ms.htm. The protocol is presumed to be HTTP, HTTPS, or FTP. The wildcard character (*) is allowed in the site specifications, this time as the left part of the specification.

  • UrlIdentityPermission  This permission identifies the full URL of the site from which the code originates. The attribute class has one property, Url, of type string, which contains the full URL specification, including the protocol specification and file specification—for example, http://oursite.microsoft.com/apps/foo/zzz.html. The wildcard character is permitted, this time as the right part of the specification—for example, http://oursite.microsoft.com/apps/foo/*.

Custom Permissions

The custom permissions, similar to those already defined in the .NET Framework class library, describe access rights to various resources. Once defined, a custom permission can be used in exactly the same way as any “standard” permission. Custom permissions are introduced, as a rule, when it’s necessary to describe access to some new kind of resource not covered by existing permissions, such as a new input or output device.

tip

It’s a bad practice to try to redefine existing permissions as custom permissions. It is possible to do so, but having multiple permissions pertaining to the same resource can only create pain for the system administrators, who must then keep an eye on all alternative “doors” leading to the resource. As a matter of practical advice: don’t make system administrators any unhappier than they already are; it might cost you.

To define a custom permission, you’ll need to do the following:

  1. Define the new permission class.

  2. Define constructors and methods of the permission class according to the permission semantics.

  3. Define the methods implementing the [mscorlib]System.Security.IPermission interface: Copy, Intersect, Union, IsSubsetOf, and Demand.

  4. If, in principle, full access to the resource can be granted, define the IsUnrestricted method implementing [mscorlib]System.Security.IUnrestrictedPermission.

  5. Define the methods implementing the [mscorlib]System.Security.ISecurityEncodable interface that provide the XML encoding and decoding of the permission: FromXml, ToXml.

  6. If necessary, define the GetObjectData method implementing the [mscorlib]System.Runtime.Serialization.ISerializable interface.

  7. Define the accompanying attribute class.

  8. Add support for declarative security.

  9. Add the mechanism enforcing the permission wherever the associated resource is exposed.

  10. Modify the security policies to take your new permission into account.

Needless to say, the preceding list is meant to discourage you from defining custom permissions .

The best way to define a custom permission is to pick a standard permission whose semantics resemble your intended semantics most closely and use it as an example. It’s always a good idea to derive the custom permission classes from [mscorlib]System.Security.CodeAccessPermission and the accompanying attribute classes from [mscorlib]System.Security.Permissions.CodeAccessSecurityAttribute.

One of the major design problems in defining a custom permission is the question of the granularity of the resource access description. In other words, what level of detail is adequate to describe the protected resource? If you were designing RegistryPermission, for example, your choice of granularity could range from a 1-bit indication of whether or not full access to the registry is granted to a detailed description of a specific kind of access to a specific registry node.

Generally, four basic principles should guide your approach to permission granularity:

  • Total Boolean, which grants or denies access to the resource.

  • Total enumerated, which grants one of the specified (enumerated) forms of access to the resource.

  • Listed Boolean, which grants or denies access to the resource components listed in the permission declaration.

  • Listed enumerated, which grants one of the specified forms of access to the resource components listed in the permission.

Although additional questions might arise about the level of detail involved in the access form enumeration and the resource components list, the four basic principles, I think, stand. You are welcome to introduce a fifth and put me to shame.

A custom permission class must implement the ISecurityEncodable interface with its methods ToXml and FromXml, to encode the permission in XML form and restore the permission object from the XML text. The outermost tag of the XML encoding is Permission:

<Permission     version="1">        </Permission>

To support the declarative security mechanism built into the common language runtime, the custom permission class must be accompanied by the attribute class. The attribute class must have properties that correspond to the parameters of the permission class’s constructors. The attribute class must also implement at least one variant of the CreatePermission method. The custom attribute System.AttributeUsageAttribute must be assigned to the attribute class, defining its possible targets, inheritance, and multiplicity, as described in the section “Classification of Custom Attributes,” in Chapter 13, “Custom Attributes.”

Enforcing a newly created custom permission is the easy part; the items dealing with the new resource must create security objects from the custom permission and also security actions, such as Demand, Assert, and so on. The simplest way to do this is to assign the security custom attribute to the respective item.

The last step in creating a custom permission is updating the security policies to include the permission. This is done by writing an XML descriptor of the custom permission and invoking the code access security policy tool, Caspol.exe:

caspol   addset  cust_perm.xml  cust_perm_name

Then, again by using the Caspol.exe utility, a new code group must be added or the existing one changed, to specify the code identities that will be granted the custom permission. Operation of the Caspol utility is rather complicated and well beyond the scope of this book; for information, you can refer to the documentation on Caspol and security administration included in the .NET Framework SDK.

Permission Sets

Individual permission objects (the instances of the permission classes) can be combined into permission sets. A permission set is an instance of the [mscorlib]System.Security.PermissionSet class or of the [mscorlib]System.Security.NamedPermissionSet class, which is derived from the former. A permission set can be constructed, for example, by combining all permissions relevant to a certain resource or to a certain metadata item (the assembly, a class, or a method).

The PermissionSet class, after its constituent permission classes, implements the interface IPermission with its methods Copy, Intersect, Union, IsSubsetOf, and Demand.

The unnamed permission sets constructed on a per-data-item basis, pertinent to a certain type of security action, form the metadata representation of the declarative security.



Inside Microsoft. NET IL Assembler
Inside Microsoft .NET IL Assembler
ISBN: 0735615470
EAN: 2147483647
Year: 2005
Pages: 147
Authors: SERGE LIDIN

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net