Last week we looked at sandboxing and the v4 CLR – with the key change being that the CLR now defers exclusively to the host application when setting up sandboxed domains by moving away from the old CAS policy model, and moving instead to simple sandboxed AppDomains.
This leads to an interesting situation when your program calls APIs that assume the presence of CAS policy, either implicitly [for example, Assembly.Load(string, Evidence)] or explicitly [for example SecurityManager.PolicyHierarchy]. These APIs require CAS policy in order to return correct results, however by default there is no longer CAS policy to apply behind the scenes anymore.
Let’s take a look at what happens if these APIs are called, and what should be done to update your code to take into account the new security policy model.
(In addition to this blog post, the CLR security test team is preparing a set of blog posts about how they moved our test code base forward to deal with these and other v4 security changes – those posts will provide additional advice about how to replace uses of obsolete APIs based upon the real world examples they’ve seen).
In general, APIs that assume the presence of CAS policy have been marked obsolete, and will give a compiler warning when you build against them:
Additionally, these APIs will throw a NotSupportedException if they are called at runtime:
(In the beta 1 release, this message is slightly different:)
Let’s take a look at the set of APIs which make implicit use of CAS policy first, and then see what they might be replaced with in a v4.0 application.
The general way to recognize an API which is implicitly using CAS policy is that they tend to take an Evidence parameter which was used to resolve against CAS policy and provide a grant set for an assembly. For instance:
It’s important to note that although these APIs all take Evidence parameters, the concept of Evidence itself is not deprecated and continues to exist (and even enhanced in v4.0 – but that’s another show). Evidence itself is still a useful tool for hosts to use when figuring out what grant sets they want to give assemblies. The common thread with these APIs is that they used the Evidence to resolve against CAS policy – and it’s the CAS policy portion that’s been deprecated in v4.
Let’s say that your application is using one of the Evidence-taking overloads of these APIs, and thus had an implicit dependency on CAS policy. Figuring out what to replace the API call with depends upon what your application was trying to accomplish with the API call.
We’ve found that commonly the goal of calling one of these APIs was not to sandbox the assembly being loaded, but rather to access other parameters on the overload which may not be available without also providing Evidence. In these cases, you can go ahead and just drop the Evidence parameter from the API. We’ve ensured that all of the above APIs now have overloads that provide the full set of parameters without requiring an Evidence parameter.
Additionally, in many cases we’ve found that code passes in Assembly.GetExecutingAssembly().Evidence or simply null to the Evidence parameter. In both of those cases, it’s safe to simply call an overload of the API which does not require an Evidence parameter as well.
The other reason to provide Evidence when calling these APIs is to sandbox the assembly in question. The correct way to do this in v4 (and the best way to do this in v2.0 and higher of the .NET Framework) is to simply load the assembly into a simple sandboxed AppDomain. The assembly will then be sandboxed by virtue of the fact that it’s loaded in the sandboxed domain, and you will no longer need to load the assembly with an Evidence parameter to restrict its grant set.
I’ve listed the benefits of using simple sandboxed domains before, and they continue to apply in this scenario. For example, using a simple sandbox rather than an Evidence resolve to sandbox assemblies allows your application:
So, to summarize, if you’re using one of the Evidence taking APIs which would have resolved an assembly’s grant set against CAS policy in the past:
Next time, I’ll look at the explicit uses of CAS policy, and what their replacements should be.