Architecture and Terminology


To get the full benefit of this chapter, you need to be aware of the terminology and concepts related to CAS.

Identity-Based Security

When it comes to security paradigms, there are two different flavors: user identity-based security and code identity-based security. With user identity-based security, authentication takes place for particular user identities. During authorization, user credentials are mapped to specific resource access rights. The result of this security approach is that every code run on behalf of a user is executed with the same access rights. In the Microsoft .NET Framework, the implementation for this type of security is known as role-based security.

The other, newer security paradigm is code identity-based security. Code identity-based security is complementary to user identity-based security because it allows you to specify security settings based on the identity of code. For example, you can decide to allow the execution of any program located within your company's intranet.

Code Access Security

Code access security (CAS) is the .NET Framework answer to implementing code identity-based security and, as such, is the foundation of security in the .NET Framework. By combining user identity-based security and CAS, you can not only specify a set of privileges and restraints for a specific group or user, you can also assign different levels of trust to code with varying code identities executed by the same user.

Permissions

Permissions constitute the most fine-grained elements of CAS. A permission represents the fact that code is allowed to perform a specific operation. Every permission has a type and a scope. Permission types apply to different kinds of resources: Microsoft .NET defines 25 permission types-for example, the Registry permission type that grants permission to read, write, or create registry keys, and the Printing permission type that grants permission for printing operations.

Note 

You can find more information about the predefined permission types in Microsoft .NET at http://msdn2.microsoft.com/en-us/library/h846e9b3.aspx.

Permission scopes refer to the amount of freedom a permission provides. Permission scopes can vary from narrow (for example, the permission to read a file) to unrestricted (for example, permission to do anything with a file).

.NET assemblies typically require a collection of individual permissions to be able to function correctly. Such collections are called permission sets. .NET provides six predefined permission sets:

  • Nothing

  • Execution

  • Internet

  • LocalIntranet

  • Everything

  • FullTrust

These predefined permission sets are also known as the named permission sets. The FullTrust permission set is the most liberal of the named permission sets; it allows code to perform all operations.

Security Evidence

Code access security allows you to specify security settings based on the identity of .NET assemblies. The proof provided by .NET assemblies regarding their identity is called security evidence. Security evidence can be divided into two categories: origin-based evidence and content-based evidence.

Origin-based evidence is completely independent of the actual content of an assembly. The .NET common language runtime (CLR) only examines where the assembly is coming from. The standard locations known in origin-based evidence are current application directory, Global Assembly Cache (GAC), Site, URL, and Zone.

Content-based evidence examines the actual content of a .NET assembly. The .NET CLR looks for content-based evidence in the form of strong names, publisher identity, and assembly hash codes. Strong-named assemblies have fully qualified assembly names that include the assembly name, version number, culture (which always needs to be set to neutral for assemblies containing code), and the developer identity in the form of a public key token.

Note 

In Visual Studio .NET 2003, strong-name key files consisting of public/private key pairs had to be created manually by using the strong-name tool (sn.exe). Next, a manual reference to the strong-name key file had to be included in the AssemblyInfo file of a .NET project. In Visual Studio 2005, the integrated development environment (IDE) makes it easy to sign assemblies with strong names. If you right-click the project file and choose Properties, you can click the Signing tab and generate a strong-name key file and sign the assembly from within the Visual Studio 2005 IDE. You can find more information about the strong name tool at http://msdn2.microsoft.com/en-us/library/k5b5tt23.aspx.

Assemblies that include publisher evidence are digitally signed with a certificate via the SignTool.exe command-line utility. Hash evidence is the most stringent form of evidence available. Hashes are calculated based on the contents of an assembly, so if a line of code in the assembly changes, the hash changes as well. Because of this, security policies based on hash evidence are very secure and very maintenance intensive.

As an administrator, you should use content-based evidence instead of origin-based evidence because content-based evidence is more accurate. Builders of frameworks, such as Microsoft itself, will typically prefer to specify default security policies based on origin-based evidence because they will never have enough insight into the solutions built using their framework to apply a meaningful security policy based on content-based evidence.

Security Policies

A code group associates a permission set with evidence. If a .NET assembly satisfies some kind of evidence, it is granted the rights in the permission set specified in the code group. A .NET security policy is a collection of code groups. The code groups within a security policy are completely independent of each other. The .NET CLR evaluates which code groups apply to a given assembly based on the evidence satisfied by the assembly and grants the union of the rights of all permission sets specified in the code groups. SharePoint defines two custom security policy files: WSS_Minimal and WSS_Medium. The SharePoint security policy files are discussed in the "Reading Security Policy Files" section of this chapter.

.NET allows administrators to provide multiple security policies, and multiple security policies can apply to the same assembly. The actual permissions that are granted to an assembly are the intersection of all permissions granted by all security policies.

There are four types of security policies:

  • Enterprise policy Defines a policy that affects all computers within the entire enterprise.

  • Machine policy Defines a policy for a specific computer.

  • User policy Defines a policy for a specific user.

  • Application-domain policy Defines a policy for all code running in a specific application domain. The default application-domain policy grants code full trust. The WSS_Minimal and WSS_Medium security policies are examples of application-domain policies.

Note 

Application domains are the fundamental scope for execution of code and ownership of resources in .NET. .NET objects always reside in exactly one application domain.

Calculating Permissions for Assemblies

In this section, you will learn about the process executed by the .NET common language runtime (CLR) to calculate which permissions apply to a .NET assembly.

When the .NET CLR loads an assembly, it computes the permissions the assembly is granted by calculating the permissions granted by all security policies. This set of permissions is calculated only once per application domain and is stored in memory for as long as the assembly remains loaded. If an assembly decides to invoke a class located in another assembly, that class might demand that the calling assembly have the required security permissions to access it. In such cases, to prevent luring attacks, it is not sufficient to check that the assembly that immediately invokes the class has the required permissions.

Note 

A luring attack occurs when code with a low level of trust attempts to get code with a high level of trust to do something on its behalf. This is also known as a middleman attack.

Not only do you need to know the permissions associated with the immediate caller, the .NET CLR must determine that every assembly up the call chain has the required permissions. This is also known as the security permission stack walk.

image from book
Stack Walks

In essence, a stack is just a list of data. New items added to the stack are placed on the top (push); items removed from the stack are also taken from the top (pop). The stack is used to keep track of different kinds of short-term data. A stack consists of different layers (or stack frames) that contain method arguments, local variables, and return addresses for each method that is executing within a program. The method stack frame can be used to trace the return path through nested method calls, which is required to determine the complete method call chain. This process occurs during the security stack walk.

image from book

Stack Walk Modifiers

In code, developers are allowed to modify the behavior of the stack walk via assertions, demands, denies, and permit only stack walk modifiers. As an administrator, you will not work with stack walk modifiers directly, although you must be aware of their existence if you want to understand all factors affecting code access security in general and the problems surrounding partially trusted callers in particular. Partially trusted callers are discussed in detail later in this chapter, in the "Partially Trusted Callers" section.

Developers can assert a security permission, which stops the stack walk in the stack frame doing the assertion. This is useful because stack walks can be quite expensive with regard to performance.

Note 

During the SharePoint 2007 beta phase, .NET performance profiling showed that the performance hit caused by complete stack walks ranged between 6.5 percent and 11 percent, illustrating that stack walks can have significant impact on performance.

One way to mitigate such performance hits is to assert security permissions. The downside of this approach is that callers further up the call chain might not have the required permissions to perform operations carried out by downstream objects. However, the assembly containing the assertion must be granted the permission it tries to assert, and only assemblies that are granted the Security permission are allowed to assert permissions.

A security demand triggers a stack walk demanding a given permission of all callers up the stack. In other words, during the stack walk, the complete method call chain is visited to determine if callers have sufficient permissions. If the .NET CLR discovers an assembly in the call chain that is not granted the demanded permission, the stack walk aborts and a security exception is raised. Security demands are useful in scenarios where the code is about to perform some sort of intensive operation that ultimately requires a specific permission. If the assemblies in the call chain do not have this permission, the operation will eventually fail. In such scenarios, it makes sense to ensure that the required set of permissions is granted before undertaking an intensive operation that takes up time and CPU processing power.

A security deny overrides administrative security policy and sets a stricter security policy programmatically. This is a technique often applied by third-party vendors, because they want to create secure components that are deployed in an environment that is not well known to them.

Permit only stack walk modifiers are the opposite of security denies. They are used to define which permissions are allowed, even if other permissions are granted administratively. Again, third-party vendors often use this technique.

Declarative Security

Code access security offers a mechanism to define security permissions programmatically as well as declaratively via security attributes. If you are an administrator, you are not likely to use programmatic or declarative forms of security permissions directly. However, it can be helpful to be aware of the concepts involved because you are likely to encounter .NET developers who make use of these security techniques. In addition, defining security permissions programmatically and declaratively helps Visual Studio 2005 to do a static analysis of the required permissions for a given assembly, which is helpful to administrators who want to determine the minimal permission set for a given assembly. Performing a static analysis of required permissions is discussed in the "Calculating the Required Assembly Permission Set" section of this chapter.

Best Practices 

Defining security permissions declaratively instead of programmatically helps to prevent cluttered code, which is a good thing for developers. Another advantage that is discussed less often is that using security attributes consistently makes it quite easy to determine the minimum set of permissions required to run code.

The following code listing shows examples of both models for defining security permissions. The ProgrammaticSecurity() method shows how to define the permission to read a file programmatically. The DeclarativeSecurity() method shows how to define the same permissions declaratively.

 using System; using System.Security.Permissions; namespace MyNamespace {   class MyClass   {     private void ProgrammaticSecurity()     {       FileIOPermission permission = new FileIOPermission(       FileIOPermissionAccess.Read, @"c:\test.txt");       permission.Demand();       // code that reads test.txt     }     [FileIOPermission(SecurityAction.Demand,     Read = @"c:\test.txt")]     private void DeclarativeSecurity()     {       // code that reads test.txt     }   } } 

For every permission attribute, you need to specify a security action. You already know four of them:

  • Assert

  • Demand

  • Deny

  • PermitOnly

The meaning of those security actions are identical to the meaning of stack walk modifiers that can be defined programmatically and that were discussed in the previous section.

In addition to those four security actions, you can choose from a wider range of security actions that is not available with programmatic security techniques:

  • DemandChoice Choice actions allow you to combine permissions in a logical OR. If you want to demand that a method is granted either one of two or more permissions, you should use the DemandChoice security action. You can apply this action to classes and methods.

  • InheritanceDemand This security action is used to demand a permission from any subclass of a given class. You can apply this action to classes and methods.

  • InheritanceDemandChoice This security action is a combination between a choice action and an inheritance action. Please refer to DemandChoice for more information about choice actions. Please refer to InheritanceDemand for more information about inheritance actions. You can apply this action to classes and methods.

  • LinkDemand This security action can be used to demand a permission at link time instead of call time, during Just-In-Time (JIT) compilation. This eliminates the stack-walk penalty, but you need to be aware that link time demands are calculated only during JIT compilation for the first caller up the call chain. Subsequent calls to the same method by other callers are not verified to have the required permissions. As a result, using LinkDemand leaves you more open for luring attacks. You can apply this action to classes and methods.

  • LinkDemandChoice This security action is a combination between a choice action and a link demand action. Please refer to DemandChoice for more information about choice actions. Please refer to LinkDemand for more information about link demand actions. You can apply this action to classes and methods.

  • RequestMinimum This security action indicates that a given permission is the minimum permission required for the target assembly to be able to execute. For example, if an assembly claims it needs to read a file via a RequestMinimum action, the assembly will not execute unless this permission is granted. You can apply this action only to an assembly.

  • RequestOptional This security action specifies optional permissions that can be granted to an assembly. You can apply this action only to an assembly.

  • RequestRefuse This security action specifies permissions that are not allowed to be granted to an assembly. You can apply this action only to an assembly.




Microsoft Office Sharepoint Server 2007 Administrator's Companion
MicrosoftВ® Office SharePointВ® Server 2007 Administrators Companion
ISBN: 0735622825
EAN: 2147483647
Year: 2004
Pages: 299

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