Differences Between the Security Rule Sets

In my last post I talked about the two different security rule sets supported by the v4 CLR.  At a high level, level 1 is the v2.0 security transparency model, and level 2 encompasses the updated v4 security transparency model.  Digging down a little deeper, it’s interesting to look at some of the exact details that change between the various transparency models.  For fun, let’s also compare both rule sets to Silverlight.

A couple of interesting things to notice – the level 2 rules look quite similar to the Silverlight rules.  This means that you can basically learn one set of core security enforcement rules and apply them to both desktop and Silverlight development.  As I mentioned previously, it’s also interesting to note that the penalty for transparency violations in level 2 transparency are generally hard failures, while the penalty in level 1 was generally triggering a full trust demand.  That means that many of the level 1 transparency violations are generally more expensive (since they incur a runtime check at each invocation, rather than a single JIT time check).  They also have a tendency to hide on you, since runtime checks can sometimes succeed during testing, and fail once you deploy your app to a new environment.

In the interest of completeness, I’m going to list several things in this table that I have yet to blog about.  (Although, you’ll recognize many of the core transparency rules covered here.) Over the next few weeks, I should cover the various interesting pieces of this table – but rather than waiting to blog about them before adding them here, I think it would be more useful to list the full table now.

I’ll also note that while level 1 transparency is supported in the v4 runtime, it exists solely for compatibility with existing code.  No new code should be written using the level 1 rule set, and over time existing code should consider moving to the level 2 rule set as well.  (That is, don’t necessarily treat this chart as a way to select which security rule set you want to work with, but rather as a way to compare the evolution of transparency from .NET 2.0, to Silverlight 2, and finally into .NET 4).

  Level 1 (v2) Level 2 (v4) Silverlight 2
Introduced in .NET 2.0 .NET 4 Silverlight 2
Default for Assemblies built against runtimes prior to v4 Assemblies built against the v4 runtime Silverlight assemblies
Explicit attribute [assembly: SecurityRules(SecurityRuleSet.Level1)] [assembly: SecurityRules(SecurityRuleSet.Level2)] N/A – all assemblies use the Silverlight transparency model
Attribute to create a mixed transparency assembly (containing a combination of critical, safe critical, and transparent code in a single assembly) [assembly: SecurityCritical(SecurityCriticalScope.Explicit)] [assembly: AllowPartiallyTrustedCallers] N/A – platform assemblies are all mixed transparency, application assemblies are all fully transparent
Effect of the APTCA attribute Allows partial trusted callers access to the assembly by removing an implicit link demand for full trust on all code in signed assemblies. Allows partial trusted callers access to the assembly by making all code in the assembly transparent by default. (Although the assembly can explicitly make some of the code critical or safe critical.) N/A – Silverlight does not have the AllowPartiallyTrustedCallers attribute
Publicly visible security critical members are implicitly safe critical Yes – there is no such thing as a publicly visible safe critical API in level 1 transparency. No – only APIs explicitly annotated as SecuritySafeCritical are safe critical. No – only APIs explicitly annotated as SecuritySafeCritical are safe critical.
Link demands should be used for JIT time security enforcement Yes – since publicly visible critical APIs are implicitly safe critical, link demands must be used to prevent JIT time access to security sensitive APIs. No – since code must be critical to access either a link demand or a public critical API, level 2 transparency deprecates the use of granular link demands in favor of simply protecting security sensitive APIs by keeping them security critical. No – Silverlight does not support link demands.
Result if a transparent method attempts to call a method protected by a link demand The link demand is converted into a full demand at runtime, which may fail with a SecurityException. A MethodAccessException will be thrown at JIT time. N/A – Silverlight does not support link demands.
Result if a transparent method attempts to call unmanaged code A demand for SecurityPermission/UnmanagedCode will be triggered at runtime, which may fail with a SecurityException. A MethodAccessException will be thrown at JIT time. A MethodAccessException will be thrown at JIT time.
Result if a transparent method has unverifiable IL A demand for SecurityPermission/UnmanagedCode will be triggered at runtime, which may fail with a SecurityException. A VerificationException will be thrown at JIT time. A VerificationException will be thrown at JIT time.
Result if a transparent method attempts to perform a security assert An InvalidOperationException is thrown at runtime. An InvalidOperationException is thrown at runtime. N/A – Silverlight does not support security asserts.
Result if at transparent attempts to call a critical method If the method is:
  • Within the same assembly – a MethodAccessException is thrown at JIT time.
  • In another level 1 assembly – N/A (level 1 publicly visible critical code is implicitly safe critical, so there is no violation).
  • In a level 2 assembly – the critical code is treated as safe critical with a link demand for full trust.  This, in turn, triggers a runtime demand for full trust which may fail with a SecurityException.
A MethodAccessException is thrown at JIT time. A MethodAccessException is thrown at JIT time.
Transparency of partial trust assemblies Fully transparent – all transparency annotations are ignored for partial trust assemblies. Fully transparent – all transparency annotations are ignored for partial trust assemblies. Application assemblies are fully transparent – all transparency annotations are ignored for them.
Default transparency for assemblies which are security agnostic All types are transparent, all methods are safe critical. All types and methods are security critical (except where this would violate inheritance rules). N/A – all Silverlight assemblies are exposed to the sandbox.
Protection for non-APTCA assemblies being used by partial trust code Provided to all signed assemblies by adding an implicit link demand for full trust to all code within the signed assembly. Provided to all fully trusted assemblies because all of the types and methods within a non-APTCA assembly are security critical by default (see above). N/A – all Silverlight assemblies are exposed to the sandbox.
Fully transparent assemblies are exposed to partial trust No – signed fully transparent assemblies still have an implicit link demand for full trust unless they are additionally marked APTCA Yes – no additional APTCA attribute is required for fully transparent code. Yes
Critical members can be converted to safe critical members protected by a link demand for FullTrust No Yes.  If a publicly visible security critical method is called by a security transparent level 1 method, the CLR will treat the critical method as if it was safe critical with a link demand for full trust on it.  (If the caller is level 2, this conversion does not occur). No
Security critical annotations support both applying to a larger scope (type, assembly, etc) and all of its contained members, or only the scope itself Yes.  The SecurityCriticalScope enumeration is used to toggle between having a SecurityCritical attribute apply to only the container (SecurityCriticalScope.Explicit) or the container and all of its members (SecurityCriticalScope.Everything) No.  SecurityCriticalScope is not used in level 2 assemblies, and is ignored if it is provided.  All security critical attributes implicitly use SecurityCriticalScope.Everything. No.  All SecurityCritical attributes implicitly use SecurityCriticalScope.Everything.
Members introduced within a security critical scope can add additional attributes to become safe critical Yes.  Adding a SecurityTreatAsSafe or SecuritySafeCritical attribute within a critical scope changed the contained member’s transparency. No.  The larger scope always wins, attributes applied at smaller scopes are not considered. No.  The larger scope always wins, attributes applied at smaller scopes are not considered.
Critical or safe critical annotations at a larger scope (type, assembly, etc) introduce only to methods introduced directly in a type. Overridden virtuals and interface implementations do not use the larger scoped annotation and are transparent by default. No, the outer scope applies to all contained members. Yes.  Since the transparency of the members not introduced by the local type are not under its direct control, overrides and interface implementations must restate their intended transparency. Yes.
Can define security critical attributes that are protected from use by partial trust code No.  Link demands must be used for this purpose. Yes.  Security critical attributes cannot be applied to transparent targets. Yes.
If reflected upon, security critical targets trigger a security demand No, although link demands do become full demands under reflection. Yes.  Reflecting upon a level 2 security critical target will trigger a full demand for full trust.  This happens based upon the target of the reflection, not based upon the code that is performing the reflection operation.  (For example, level 1 code reflecting on a level 2 critical method will still trigger the demand). Yes.  Transparent code may not reflect upon critical code.
Delegate binding rules are enforced No. No. Yes – Silverlight contains delegate binding rules that prevent critical delegates from being bound to transparent targets and vice versa.