Transparency as Enforcement in CLR v4
Now that we know the basics of security transparency, let's look at how it evolved over time. In .NET v2.0, many of the transparency rules we previously looked at were in place, with the exception of some of the inheritance rules that were introduced for the first time in the Silverlight transparency implementation.
However, in .NET 2.0 transparency was used as a security audit mechanism rather than a security enforcement mechanism. This means that:
- There is no cross-assembly transparency enforcement.
- Transparency violations were generally "soft" violations and enforced via a demand.
Because transparency was not enforced cross-assembly, there was no such thing as a public security critical method. Instead, all publicly visible security critical methods were implicitly security safe critical. If a publicly visible method wanted to have protection against transparent (and therefore partially trusted) callers, it needed to use a LinkDemand instead of relying on being critical.
The other fallout of the v2 transparency model being used only for security audit is that violations of the transparency rules were always allowed in full trust - after all, there's not any security risk to audit against in a fully trusted domain. This means that for most of the transparency rules, a violation resulted in a full demand for a full trust equivalent permission. (The one exception to this was the rule that transparent code may not assert - even in v2 this was a hard rule).
For example, if a transparent method tried to call native code in v2, the CLR would issue a full demand for SecurityPermission/UnmanagedCode. This demand would succeed if the whole stack was fully trusted, indicating that even though the code doing the native invoke may not have been subjected to a security audit, it was OK to proceed since the current context doesn't involve partial trust.
However, if this same code was called from within an ASP.NET medium trust AppDomain, it would fail with a SecurityException. In this scenario, the fact that the transparent code may not have been audited is more significant since partial trust is in play, so the operation was blocked.
As we moved toward using security transparency as the enforcement mechanism of Silverlight and the v4 desktop CLR, we needed to harden up these rules a bit. The first step toward doing this was to make it possible to expose security critical methods publicly. Therefore, on the v4 CLR public security critical methods are no longer implicitly security safe critical.
The fact that assemblies can now expose security critical APIs has an interesting side effect. Since code must be security critical if it wants to call a security critical API, and it must also be security critical if it wants to call an API protected by a link demand, link demand functionality is redundant.
That is, having a link demand for a granular permission requires that the caller be security critical. Since the v4 CLR requires that all security critical code be fully trusted only full trust code may call the link demand protected method. That is, calling a security critical method also requires that the caller be fully trusted and security critical; therefore there is no difference on security requirements of calling methods between an API protected with a link demand and an API protected by being marked security critical.
This, in turn, lead us to deprecate the use of link demands to protect security sensitive APIs in favor of just leaving the APIs as security critical. (In fact, one of the recommended steps when using the v4 transparency model is to remove link demands and replace them with security critical APIs instead).
The next step toward using security transparency as a full enforcement mechanism is to treat all transparency errors as hard violations, regardless of the trust context they occur in. Rather than transparency violations being converted to full demands in the v4 transparency model, they are treated as strict violations - and will unconditionally result in an exception when they are encountered. This also matches the way that Silverlight enforces its transparency model.
The exact exception that will be triggered, and the time that it is triggered, depends upon the transparency violation being encountered. For example, a transparent method trying to call a critical method will result in a MethodAccessException the first time that the JIT sees the call. However, a transparent method overriding a critical method will instead result in a TypeLoadException when the violating type is first loaded.
We already talked about the final piece of the transparency as an enforcement mechanism puzzle when we first looked at the transparency rules. The v4 CLR treats all partially trusted code as if it were fully transparent - which means that full trust code can rely on the fact that partial trust code can never use any of its security critical components without having to provide any extra protection. Instead, the full trust code can focus on exposing a safe set of security safe critical APIs and auditing those thoroughly.