Security-Transparent Code

Transparency, a new feature in the .NET Framework version 2.0, helps developers write more secure .NET Framework libraries that expose functionality to partially trusted code. You can mark a whole assembly, some classes in an assembly, or some methods in a class as security-transparent. Security-transparent code cannot elevate privileges. This restriction has three specific ramifications:

  • Security-transparent code cannot perform asserts.

  • Any link demand that would be satisfied by security-transparent code becomes a full demand.

  • Any unsafe (unverifiable) code that must execute in security-transparent code causes a full demand for the skip verification security permission.

These rules are enforced during execution by the common language runtime (CLR). Security-transparent code passes all the security requirements of the code it calls back to its callers. Demands that flow through the security-transparent code cannot elevate privileges. If a low-trust application calls security-transparent code and causes a demand for high privilege, the demand will flow back to the low-trust code and fail. The security-transparent code cannot stop the demand because it cannot perform asserts. The same security-transparent code called from full-trust code results in a successful demand.

You have to apply transparency explicitly. When you use transparency, you separate your code into security-transparent and security-critical (the opposite of security-transparent) methods. The majority of your code that handles data manipulation and logic can typically be marked as security-transparent, whereas the lesser amount of code that performs elevations of privileges is marked as security-critical. You should be able to mark approximately 80 percent of your code as security-transparent. This will enable you to focus auditing and testing efforts on the 20 percent of your code that is security-critical.

For backward compatibility with earlier versions of the .NET Framework, all code that is not annotated with transparency attributes is considered to be security-critical. There are no code analysis rules to validate transparency. Therefore, you may need to debug runtime transparency errors.

Transparency Attributes

The following table describes the three attributes that you use to annotate your code for transparency.

Attribute

Description

SecurityTransparentAttribute

Allowed only at the assembly level. Identifies all types in the assembly as security-transparent. The assembly cannot contain any security-critical code.

SecurityCriticalAttribute

When used at the assembly level, identifies all code in the assembly as security-transparent by default, but indicates that the assembly may contain security-critical code.

When used at the class or method level, identifies the class or method as security-critical. The class or method identified as security-critical can perform elevations of privilege.

SecurityTreatAsSafeAttribute

Can be applied to private or internal security-critical members to enable security-transparent code in the assembly to access those members. Otherwise, security-transparent code cannot access private or internal security-critical members in the same assembly. Doing so would influence security-critical code and make unexpected elevations of privilege possible.

The SecurityTreatAsSafeAttribute attribute enables security-transparent code to access security-critical members in the same assembly. Consider the security-transparent and security-critical code in your assembly as separated into two assemblies. The security-transparent code would not be able to see the private or internal members of the security-critical code. Additionally, the security-critical code is generally audited for access to its public interface. You would not expect a private or internal state to be accessible outside the assembly; you would want to keep the state isolated. The SecurityTreatAsSafeAttribute attribute maintains the isolation of state between security-transparent and security-critical code while providing the ability to override the isolation when it is necessary. Security-transparent code cannot access private or internal members of security-critical code unless those members have been marked with SecurityTreatAsSafeAttribute. Before applying the SecurityTreatAsSafeAttribute, audit that member as if it were publicly exposed.

Security Transparency Examples

If you want to make a whole assembly transparent to indicate that the assembly does not contain any critical code and does not elevate privileges in any way, you can explicitly add transparency to the assembly with the following attribute:

 [assembly: SecurityTransparent]

If you want to mix critical and transparent code in the same assembly, start by marking the assembly with the SecurityCriticalAttribute attribute to indicate that the assembly can contain critical code, as follows:

 [assembly: SecurityCritical]

If you want to perform security-critical actions, you must explicitly mark the code that will perform the critical action with another SecurityCriticalAttribute attribute, as shown in the following code example:

 [assembly: SecurityCritical]
Public class A
{
    [SecurityCritical]
    public void Critical()
    {
        // critical
    }

    public int SomeProperty
    {
        get {/* transparent */ }
        set {/* transparent */ }
    }
}
public class B
{    
    internal string SomeOtherProperty
    {
        get { /* transparent */ }
        set { /* transparent */ }
    }
}

The previous code is transparent except for the Critical method, which is explicitly marked as security-critical. Transparency is is the default setting, even with the assembly-level SecurityCriticalAttribute attribute.