Introduction to Microsoft Office SharePoint Server and WSSv3 Trust Levels and Code Access Security
Trust levels are an integral portion of SharePoint security and how your application architecture will interact with users. Trust levels are integrally tied into the concept of Code Access Security (CAS) in SharePoint, and how that code interacts with various security decisions. Typically, when executing code in an application environment, the context of that application will assimilate the identity of the user, regardless of what the arbitrary application may be. This however differs in SharePoint, which leverages the concept of Code Access Security in order to determine what code should be run within the SharePoint environment. CAS, at first glance can appear very confusing, but rather, once the concept and architecture that builds CAS is understood it is a very powerful concept.
Defining Trust Levels Within SharePoint
There are various CAS trust levels that SharePoint can run under, each which has its owns implications and after effects, and deciding which to leverage dictates a through analysis before implementing each within your SharePoint environment. As developers of the previous version of SharePoint can attest to, establishing the trust levels for your custom WebParts that are developed can prove rather problematic. The trust levels that are managed are saying exactly what classes your code can call out of the .NET framework as well as how that code is managed and leveraged within the SharePoint application, and although developing the actual WebPart is straightforward, how to properly implement it within your SharePoint environment tends not to be. These trust levels exist on the actual SharePoint machine as provided by the ASP.NET 2.0 framework, and can be modified or added to with custom policy files as deemed appropriate. It is somewhat common since it is the default for vanilla ASP.NET application to implement full trust, however is incredibly poor code access security practice.
The Various Trust Levels of SharePoint
There are several standard default trust levels that you get with SharePoint; full trust, high trust, medium trust, low trust, and minimum trust. With full trust all code that is implemented is allowed to run in essence, it is allowed to call any class within the .NET framework and can call pretty much any operation on the local machine. This can be a dangerous level to implement, since it will allow SharePoint WebParts to call operations on the machine that although are quite powerful, can prove dangerous to the machine. High trusts, and any subsequent trust levels, are considered partial trust, since they don’t allow full trust as the previously described level does. The next level of trust is high trust. High trust when implemented in SharePoint is simply that your SharePoint WebParts can not call native unmanaged code, which is defiantly a good thing. When defining the level as high, it will significantly reduce the threat to your SharePoint environment and is definitely the first step to implemented proper SharePoint security. Medium trust is the next trust level, and is typically within an implementation where there are multiple SharePoint instances hosted on a singular machine, where it is important to maintain a more granular level of permissions across a shared environment. The largest restriction that gets placed on applications that are running in medium trust is that it inherits the restriction of not being able to call the win32 API’s from the high trust level, and in addition restricts reading and writing to anything outside of the SharePoint instance, i.e. where you provision your SharePoint web application structure. You can easily find this by doing an explore through the IIS MMC which will show you the exact path that the code will be able to write. Low trust is the next trust, and is the most restrictive trust, and is typically if you are not running and code on the web server at all, is a good level of trust. It s a typically trust level implemented by default when implemented COTS software that doesn’t have several .aspx pages that exist on the filesystem. In MOSS and WSSv3, there is a modified level of low trust that is implemented by default, however this can obviously be extended with the trust levels that we have talked about thus far. The last trust level to be discussed is that of minimal trust, and minimal locks down the levels available to the developer to a large extent. When running under minimal trust, it means that all WebParts and custom application hooks into SharePoint will not be able to call classes that could at any point possible cause a security compromise of the SharePoint environment. This is a good practice for sheltered SharePoint environments for one overlying reason. When developing WebParts, you can sign them in order to bind them with a strong name, and then deploy them into the Global Assembly Cache (GAC). Only a user with local administrator privileges within a SharePoint server can install various assemblies to the GAC, and therefore deploying code that could potentially cause undue security problems is locked down to simply an administrative task, whom can firstly examine and analyze the code before deploying it to the production SharePoint server.
Partially Trusted Callers
One of the largest differences that a developer will see within MOSS and WSSv3 is that there is within the assemblyinfo file within there project file in the system.security namespace partially trusted callers. Now that we have seen what a partial trust class is, we can see that when under certain trust levels the code will not be able to call various interops, however in the aseemblyinfo file you can set the partially trusted attribute to true to bypass this restriction in your code when needing to make such actions.
Permission Sets and Code Groups
As discussed previously, the central concept to understand in terms of trust levels is CAS, which is discussed more exhaustively in other articles. In other articles the idea of a permission set was discussed which deserves some examination in this current context since it plays a heavy role in the concept of trust levels with SharePoint. As defined in the CAS article, a permission set is simply a way of lumping code restrictions into a manageable group that can be applied to singular or multiple sets of code that are going to run within your SharePoint environment. This is a very powerful configuration concept since it allows a developer to define new permissions to apply to code when it is necessary, when the standard permission sets the ASP.NET 2.0 doesn’t give by default. Within ASP.NET 2.0, there are a few default permission sets that are defined by default: FullTrust, Nothing, and ASP.Net. Each of these, as well as we will see with custom permission sets, are defined within the < PermissionSet /> node in the web.config file, and within this node, there are several child elements that can be defined that can be used to either extend/change the default permission sets or modify custom created permissions that you leverage against your code. In this, the permission sets have to bound to a specific set of code to be useful, as opposed to something that is applied at a global level. The major concept that binds the permission set to a specific piece of code is code evidence, which defines things such as where the compiled code is located, signatures on the compiled assembly, and other various pieces of information, and once the evidence is there, the evidence can be then used in to place the CAS rules against the running piece of code, called a code group, by using a membership condition. Code groups where discussed on another article on this site, however they are easily defined within the code group elements in the web.config file. The code group in essence will allow a developer to bind to a defined permission set whether it is a default permission set, or a custom defined one, and then will look at the code evidence as presented in the membership conditions for final applicability. Code groups are inherently important to concept of securely running a SharePoint environment, since they build the binding of evidence within WebPart code. Code Groups, as you may have guessed, are related to the concept of permissions sets in that each code group is associated within a defined permission set, as discussed above, so when examining the code group values in the web.config file, you will see that for each the PermissionSetName value will be set to a permission set. Within the code group, there is also a node for the conditionally membership match as discussed above, which is defined in the IMembershipCondition node, which is based on the concept of evidence as provided thus far.
Example of Default Code Groups
Code groups within the web.config a very easy to breakdown and define, they are very self explanatory and the concepts that they birth are easy to see within their XML values. For example, let’s look at the first code group that is defined, which is just the FirstMatchCodeGroup. It looks like the following:
< CodeGroup class=FirstMatchCodeGroup
version=1 PermissionSetName=Nothing >
< IMembershipCondition class=AllMembershipCondition version=1
String Replacement Values and Their Definitions
When examining the code groups, there may be some values that appear confusing, and they are string replacement values. These appear in various places when doing SharePoint development as well as traditional ASP.NET 2.0 development that may hook into SharePoint API’s. This are extremely evident when firstly examining the policy files, but appear in other places as well. The string replacements that you find are $AppDir$, $AppDirUrl$, $CodeGen$, and $OriginHost$. These are placed in these files for a very good reason, because SharePoint in essence is a very dynamic application that allows the placement of relevant files and configuration elements in various locations, the values may at times may need to be replaced at run time. The actual values that are going to be used when the replacement variables run at pretty self-evident, $AppDir$ will give the full file system path, $AppDirUrl$ will give the replacement file system path is fit for consumption that are needed in a certain format, $CodeGen$ shows where the managed code that a developer writing against SharePoint, or in a larger picture, the managed code that ASP.NET 2.0 is using, in essence where the temporary ASP.NET files lie (usually in the framework directly under the Temporary ASP.NET Files directory) and is the code that the developer defines is located, and lastly $OriginHost$ which will give will give the fully qualified URL endpoint of where the code is originating from, so for code running on this site, the OriginHost value would be http://www.sharepointsecurity.com.
Examining the Default Values of SharePoint
To get a better idea of this whole concept, examine the default permissionsets that are given by default: FullTrust, Nothing, and ASP.Net, and then I will show how to create a new permissionset that can be used if you need to create a new one for consumption into SharePoint. As well, lets look at a real world example of using code groups within our SharePoint environment to effectively restrict the permissions that are leveraged against a SharePoint WebPart.
Firstly, here is the permission set for fulltrust, the most lenient of permission sets:
< PermissionSet class=NamedPermissionSet version=1
Description=Allows full access
We can see in the above that we are allowing unrestricted access, a very open permission level.
The next permission set is that of nothing, and means that there are null permissions.
< PermissionSet class=NamedPermissionSet version=1
Description=Denies all resources, including the right to execute
The ASP.Net permission set allows various meanings that define each of the unique trust levels, and looks like the below:
< PermissionSet class=NamedPermissionSet version=1
< /PermissionSet >
Outside of the default permission sets that are defined, it is possible to define custom permissions that can be applied in regards to CAS, such as the option for I/O operations for a specific piece of code.