Is CAS dead in .NET 4?
With all the changes in the security system of .NET 4, the question frequently arises “so, is CAS dead now?”. One of the reasons that this question comes up so frequently, is that the term CAS in the .NET 1 security model was overloaded to refer to many different aspects of the security system:
- CAS policy – policy levels, code groups, and of course our old friend caspol.exe
- CAS enforcement – primarily the act of demanding and asserting permissions
- CAS permissions – granted by CAS policy or a host to set the level of operations that an application can perform
I’ve talked in the past about the many problems with CAS policy over the years. There are versioning problems. The host doesn’t have control over the policy applied to the code it is hosting. Enterprise administrators don’t have a good way to deploy CAS policy updates. CAS policy caused managed applications to run differently from native applications, often in confusing and undesirable ways. And of course, there’s the general complexity and difficulty of use (caspol is nobody’s favorite tool).
For these reasons, in v4 of the CLR, CAS policy has been deprecated and policy decisions are instead left entirely up to the host of an application. However, the other security mechanisms that fell under the name CAS, which allow hosts to configure AppDomains to host sandboxed code and allow library authors to write a safe APTCA library exposing services to partial trust absolutely still exist and are supported.
For instance, when a host sets up a sandboxed AppDomain to run code in, it does this by figuring out what grant set should be given to an application and supplying that grant as a set of permissions – the exact same permissions that have been used since v1 of the .NET Framework. Custom permissions can still be created by hosts or APTCA library authors to protect their libraries, and assemblies and AppDomains still receive permission objects in their grant sets.
Similarly, permissions demands are still alive and well, and are one of the most common ways that safe critical APIs in APTCA libraries will check to ensure that the sandbox they are running in supports a given operation. For example, opening a file is a security safe critical operation which demands FileIOPermission to ensure that the host has setup the current sandbox with permission to access the requested file.
What does all of this mean in practice for things like ClickOnce and ASP.NET Medium Trust sandboxes? Both ASP.NET and ClickOnce are hosts that setup sandboxes for partial trust code – which is a core scenario for the CLR that is still very much alive. ASP.NET simply sets up an AppDomain with the Medium Trust permission set (or whichever other permission set has been configured for the site in question), and all of the application assemblies loaded into that domain will receive the partial trust permission set that ASP.NET configured. If those applications try to open a file or do some other operation that is only allowed in certain sandboxes, a permission demand will be issued, and if that demand succeeds the operation will succeed.
Similarly, ClickOnce continues to work in the same way as it always had. The ClickOnce runtime sets up an AppDomain with the permissions specified in the application’s manifest and the application will run in a sandbox with that permission set. Safe critical APIs which issue demands outside of the application’s grant set will lead to security exceptions, while safe critical APIs that access resources allowed under the application’s grant set will work just like they used to.
In fact, the actual ClickOnce code really didn’t change very much at all for v4 security. Since ClickOnce has always setup homogenous AppDomains dating back to its introduction in .NET 2.0, it has never had a dependency on CAS policy at runtime!
Even though we’ve moved away from CAS policy, the CLR still provides mechanisms for partially trusted code to be setup and run – and that’s something we’ve continued to invest in making a better and safer experience. A lot of our work with security transparency in this release, for instance, was to make it safer for APTCA library authors to expose their code to partial trust. The new SecAnnotate tool was designed exactly to help ensure that more libraries could be safely exposed in a partial trust sandbox.
Recently, I was having a discussion with our security MVPs about how the overload of the term CAS is causing “CAS is dead” confusion, Keith Brown remarked to me that he prefers to think of it along these lines: .NET 4: Security just got a whole lot simpler.
Comments
Anonymous
February 24, 2010
Reading this interesting blog post, I realized there is a lot of things I didn't know. Could you point me to some resources explaining how the security model in .NET 2.0 (and 3.5 I guess) works and how it works in .NET 4.0. I would greatly appreciate!Anonymous
February 25, 2010
The security model is a pretty large topic ... I'd recommend this blog as a starting point, it's got a lot of information about how things used to be and I've been writing recently about what we're changing in v4. You could also check out MSDN (for instnace http://msdn.microsoft.com/en-us/library/dd233103(VS.100).aspx) for some other details. -ShawnAnonymous
March 31, 2010
Shawn, a question if you don't mind. Let's say you build an ASP.NET control library, for use in less than full trust level web apps. Your only exposure to SecurityCritical code is through your inheritance of the framework's ControlDesigner class. When running the app. you'll see the exception "Inheritance security rules violated by type: 'ABC'. Derived types must either match the security accessibility of the base type or be less accessible" This means you should add SecurityCritical to your type ABC - however it doesn't resolve the problem. If however you mark the assembly with "level 1" transparency, it will work (regardless of marking SecurityCritical on the type 'ABC'. APTCA is also set. If Level 1 is legacy, then what would be the correct way to do this for v4? Initially I thought that this situation was the same as bridging between transparent and securitycritical, using securitysafecritical, but making that doesn't seem to apply to subclasses. It seems like the runtime is saying "your subclass needs to be securitycritical", but, when we set the assembly to level 2, that's when the check kicks in and it decides "if the app. is partially trusted, it cannot use this assembly". Am I understanding it correctly? If I just leave the assembly as level 1, then it all seems to be OK - but what's the drawback? Level 1 might be dropped in next ver? Thanks JimAnonymous
March 31, 2010
Hi Jim, If your control assembly is partially trusted (for instance, it loads into the partial trust web app but is not loaded from the GAC), then it can never contain security critical or safe critical code. In fact, the CLR will ignore all transparency attributes it finds in the code itself and treat the assembly as if it were marked [assembly: SecurityTransparent]. Therefore, if you mark your type wtih [SecurityCritical] it's really having no effect at all - although if you were a fully trusted APTCA library that would be exactly the correct solution. The reason that the legacy level 1 rule makes this error go away is that level 1 transparency did not enforce any sort of inheritance rules at all - since level 1 is ther to be compatible with the v2 transparency model, it also cannot enforce inheritance rules. -ShawnAnonymous
April 01, 2010
Thanks Shawn, so it was OK pre-v4 because only the VS designer (full trust) would use our designer code. But now, even though asp.net doesn't use the designer code, that inheritance check is still performed. Sounds like will have to separate out the designer stuff into a different assembly. Thanks JimAnonymous
September 25, 2011
The comment has been removedAnonymous
September 25, 2011
The comment has been removed