.NET 2.0 Security Guidelines - APTCA

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Chaitanya Bijwe


Avoid using APTCA

You can override the link demand for full trust by adding the AllowPartiallyTrustedCallersAttribute (APTCA) to your assembly, as shown below, but you should do so only when it is absolutely necessary.


Use of APTCA increases the attack surface and exposes your code to partial trust callers.


Use APTCA only if both of the following conditions apply:

  • You specifically want partially trusted callers to use your strong named assembly. For example, you might need an application running on a file share to access your assembly located in the global assembly cache. However, do not open up an attack surface with APTCA if you only want fully trusted callers to use your code.
  • You have performed a thorough security code review, and your code has been rigorously audited for security vulnerabilities. Examine the resource access and other privileged operations performed by your assembly, and consider authorizing access to these operations by using other code access security demands.


The APTCA attribute is shown below.

[assembly: AllowPartiallyTrustedCallersAttribute()]


Consider using SecurityTransparent and SecurityCritical

If you know that your code will not attempt to elevate the permissions of the call stack—for example, by using assertions or stack walk modifiers—consider marking the code with the System.Security.SecurityTransparentAttribute. This is particularly useful if your code calls untrusted code such as a third-party plug-in. If the untrusted code attempts to manipulate the permissions of the call stack, a security exception is generated. Security transparent code and the code it calls give up the right to elevate the permissions of the call stack.


In addition to providing added protection when calling untrusted code, marking code explicitly with the SecurityTransparent and SecurityCritical attributes helps people who have to review your code. Typically, the majority of your code will not elevate code access security permissions, and can therefore be marked as SecurityTransparent. The small amount of your code that actually performs elevations of privilege should be marked as critical. This helps reviewers to focus on those areas of code marked as security critical.


Note Because a transparent assembly cannot be used by partially trusted code to increase its effective permission set, any assemblies that are marked transparent do not require as thorough of a security audit as standard APTCA assemblies.


Marking an assembly SecurityTransparent forces it to abide by the following rules:

  • It cannot assert permissions to stop a stack walk from continuing.
  • It cannot satisfy a link demand. Instead, any link demands on APIs called by the transparent assembly are automatically converted into full demands.
  • It cannot automatically use unverifiable code, even if it has SkipVerification permission. Instead, a full demand for UnmanagedCode occurs.
  • It cannot automatically make calls to P/Invoke methods, even if it has been decorated with the SuppressUnmanagedCodeAttribute. Instead, a full demand for UnmanagedCode occurs.


Note By default, all assemblies compiled for .NET 1.x and .NET 2.0 are security critical and contain only critical code.


To make an entire assembly transparent, you can explicitly add SecurityTransparent to an assembly by using the following attribute:

[assembly: SecurityTransparent]


This indicates that the assembly does not contain any critical code, and does not elevate the privileges of the call stack in any way.


If you need to mix critical and transparent code in the same assembly, start by marking the assembly with the System.Security.SecurityCriticalAttribute as shown here.

[assembly: SecurityCritical]


By marking the assembly with the SecurityCriticalAttribute, you indicate that the assembly can contain critical code. However, unless explicitly marked as critical, all code within the assembly defaults to being transparent. If you want to perform security critical actions, you must explicitly mark the code that will perform the critical action with another SecurityCritical attribute, as shown in the following example.

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

   public int SomeProp
   {
       get {/* transparent */ }
       set {/* transparent */ }
   }
}
public class B
{
   internal string SomeOtherProp
   {
       get { /* transparent */ }
       set { /* transparent */ }
   }
}


All of the code above is transparent (the default setting even with the assembly level SecurityCritical attribute), with the exception of the method Critical, which is explicitly marked as critical.


You can also mark all code within an entire class as critical. To do so, use the SecurityCritical attribute at the class level, and then pass SecurityCriticalScope.Everything, as shown in the following example.

[assembly: SecurityCritical]

[SecurityCritical(SecurityCriticalScope.Everything)]
public class MyClass
{
 ...
}
Personal tools