I'm new C# and am trying to understand the new security features of .NET-4.
To fill in some details, I'm currently trying to update AutofacContrib.Moq to work with the latest Moq. I had no problems doing this for .NET-3.5 and under. But in .NET-4 the security restrictions result in numerous security exceptions.
Moq has a a single method, GetObjectData
, that's marked with the SecurityCritical attribute. AutofacContrib.Moq has the AllowPartiallyTrustedCallers attribute set which is the source of the exceptions. It seems that rather than adding the SecurityRules
attribute with a SecurityLevel of 1, I'd be better off removing AllowPartiallyTrustedCallers
attribute. I believe this makes the assembly SecurityTransparent by default, which may not be sufficient (though the AutofacContrib.Moq unit tests pass).
My main question at the moment is whether assemblies targeting .NET-4 should ever use the AllowPartiallyTrustedCallers attribute? But, given that I definitely don't understand everything yet, what details should be considered when working with assemblies that are security marked? Do I need to explicitly mark my assembly with security attributes in those places it uses, directly or indirectly, something that's marked SecurityCritical
?
You are correct: in .NET 4, leaving the APTCA on there makes the assembly SecurityTransparent, and that may be what's causing you grief.
The MSDN article Migrating an APTCA Assembly to the .NET Framework 4 has a good discussion and explanation of the changes to the AllowPartiallyTrustedCallersAttribute in .NET 4.
Specifically:
The AllowPartiallyTrustedCallers attribute has changed. In v4, it no longer has anything to do with link demands. In fact, the implicit link demand that was present on signed libraries in v2 is gone. Instead, all fully trusted assemblies in v4 are, by default, SecurityCritical.
[snip /]
In v4, the effect of APTCA is to remove the automatic SecurityCritical behavior from the assembly to which it’s applied.
And...
Because the AllowPartiallyTrustedCallers attribute causes the entire assembly to be SecurityTransparent by default, the assembly’s author must specifically mark methods needing to perform privileged operations as SecurityCritical or SecuritySafeCritical.
(It's really a good article that author Mike Rousos did a great job with. I encourage you to read it in its entirety.)
If you're starting a new .NET 4 library, it's probably best to stick with the .NET 4 security model and use the appropriate SecurityCritical, SecuritySafeCritical, and SecurityTransparent attributes where needed. They're far easier to manage and understand than old code access security.
If you're migrating an old library to the new model, there's a good example in the article of how to do that... but basically it amounts to removing old LinkDemands and adding [SecurityCritical] in their place.
In your particular case, the fastest way to get going would be to add the SecurityRules attribute so you get the old behavior, but I'm not sure I'd consider that the right way. The right way would probably be to lose the APTCA and add SecurityCritical on the assembly because the assembly may contain SecurityCritical code, then mark the various types that call SecurityCritical code (e.g., stuff that references GetObjectData) with SecuritySafeCritical so your SecurityTransparent code can call it. Of course, that second approach will be a lot more work, so you'll probably want to run SecAnnotate.exe and get some automated tips.
Looking at the Moq trunk, a search for GetObjectData shows that the method in question is the override for an exception serialization mechanism (ISerializable.GetObjectData on System.Exception), which only SecurityCritical code will be calling anyway, so you may not even run into any trouble if you just lose APTCA and mark the assembly SecurityCritical.
There is an issue filed on Autofac to update it to the latest security model. If you like the idea, go vote/comment on it.
Sorry that wasn't a short answer. Security is, unfortunately, never easy. :S