Troubleshooting SharePoint CAS (Code Access Security)

Last week I spoke at the Rocky Mountain (Denver) SharePoint User Group and we talked about CAS. CAS is great because it limits what your code can do. For example– you can know that my code won’t compromise x because it doesn’t have permission to even talk to type x. It can be difficult for  developers that aren’t familiar with CAS to grasp the concepts. Typically, your project CAS requirements can be determined early on in the project lifecycle, and don’t change often over the course of development. For example– the CAS policy for NewsGator Social Sites hasn’t changed since version 1.0 over a year ago. We also NEVER ever manage CAS manually– we add the security permissions to the WSP solution package, and let SharePoint manage CAS for us.

But how do you determine what CAS settings you need? To start off with, always start off by running SharePoint in minimal trust. Also, enable debugging and the full call stack in web.config. The SafeMode node has a CallStack attribute that you’ll want to set to true. With this, you’ll get the full yellow screen of death rather than SharePoint’s happy-happy joy-joy blue screen of "an error has occurred".

With this set up– when your code encounters a CAS error, you’ll get a message similar to this:

SecurityException: Request for the permission of type ‘System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’ failed. [Full call stack follows… great reading, but you’ll have to find your own. Really, it’s not that hard to find!]

With this, we know that we need the CAS permission "System.Security.Permissions.SecurityPermission". Most permissions are conveniently located in this namespace, BTW. With this information, we can easily create the following IPermission entry in the manifest.

<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1"  />

However, there are still more attributes you’ll need to get the full/required trust that the permission can define. I don’t think I have a GREAT answer for this, but I use Reflector to get that info. Also, you can do a simple search and find the syntax– either in MSDN, exising CAS settings in the permission files in the 12 hive, particularly \12\config\wss_minimaltrust.config, or with the google. The best way to do it is to reference the type that threw the exception to see what it’s CAS requirements are. For example, I was trying to use the System.Diagnostics.Process class in some recent debug code. The error message I got from the stack trace wasn’t too complete, it just showed that the security demand failed. So I looked at Process with Reflector, and that shows the CAS that you need to work with Process.

[PermissionSet(SecurityAction.LinkDemand, Name="FullTrust"), PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
public class Process : Component {/* class here... */}

It turns out that Process requires full trust to run… so it isn’t going to run at all with partially trusted code!

Back to my earlier example– the full permission that I needed in my test case follows:

<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        version="1" Flags="ControlThread, UnmanagedCode" />

One thing I like to do is keep a reference of common CAS settings handy. Because although I LOVE typing in XML, there’s more interesting XML to hack than CAS. So keep a CAS reference handy– here’s a relatively complete sample CAS entry for one of my commercial projects. Note that it’s for an unrestricted WebPermission to make network calls– you could further lock that down to a specific URL– and it’s also for the required permission set for using SPSecurity.RunWithElevatedPrivileges.

<PolicyItem>
      <PermissionSet class="NamedPermissionSet" version="1" Description="Permission set for foo" Name="foo">
        <IPermission class="AspNetHostingPermission" version="1" Level="Unrestricted" />
        <IPermission class="SecurityPermission" version="1" Flags="Execution,ControlThread,UnmanagedCode,ControlPrincipal" />
        <IPermission class="System.Security.Permissions.EnvironmentPermission" version="1" Unrestricted="true" />
        <IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
            version="1" ObjectModel="True" Impersonate="True" UnsafeSaveOnGet="True" />
        <IPermission class="System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Unrestricted="true" />

      </PermissionSet>
      <Assemblies>
        <Assembly Name="foo"/>
      </Assemblies>
</PolicyItem>

Related reading: If you don’t know what the WSP solution package deployment is– that is a prerequisite to CAS management. Take a look at the online docs or at codeplex projects such as STSDEV or WSPBUILDER for better ways to build solution packages, or use my old-school VS project template from codeplex.com/sharepointsdk.

SHAMELESS PLUG: Want to know more about CAS? Chapter 10 of Inside Microsoft Windows SharePoint Services 3.0 has a great reference on CAS, and more great documentation on the WSS security model.

This entry was posted in SharePoint. Bookmark the permalink.

1 Response to Troubleshooting SharePoint CAS (Code Access Security)

  1. Pingback: SharePoint 2010 & CAS : le GAC n’est pas l’unique solution de déploiement de vos composants , The Mit's Blog

Leave a comment