Most code access security APIs are obsolete

Most code access security (CAS)-related types in .NET are now obsolete as warning. This includes CAS attributes, such as SecurityPermissionAttribute, CAS permission objects, such as SocketPermission, EvidenceBase-derived types, and other supporting APIs.

Change description

In .NET Framework 2.x - 4.x, CAS attributes and APIs can influence the course of code execution, including ensuring that CAS-demand stack walks succeed or fail.

// In .NET Framework, the attribute causes CAS stack walks
// to terminate successfully when this permission is demanded.
[SocketPermission(SecurityAction.Assert, Host = "contoso.com", Port = "443")]
public void DoSomething()
{
    // open a socket to contoso.com:443
}

In .NET Core 2.x - 3.x, the runtime does not honor CAS attributes or CAS APIs. The runtime ignores attributes on method entry, and most programmatic APIs have no effect.

// The .NET Core runtime ignores the following attribute.
[SocketPermission(SecurityAction.Assert, Host = "contoso.com", Port = "443")]
public void DoSomething()
{
    // open a socket to contoso.com:443
}

Additionally, programmatic calls to expansive APIs (Assert) always succeed, while programmatic calls to restrictive APIs (Deny, PermitOnly) always throw an exception at run time. (PrincipalPermission is an exception to this rule. See the Recommended action section below.)

public void DoAssert()
{
    // The line below has no effect at run time.
    new SocketPermission(PermissionState.Unrestricted).Assert();
}

public void DoDeny()
{
    // The line below throws PlatformNotSupportedException at run time.
    new SocketPermission(PermissionState.Unrestricted).Deny();
}

In .NET 5 and later versions, most CAS-related APIs are obsolete and produce compile-time warning SYSLIB0003.

[SocketPermission(SecurityAction.Assert, Host = "contoso.com", Port = "443")] // warning SYSLIB0003
public void DoSomething()
{
    new SocketPermission(PermissionState.Unrestricted).Assert(); // warning SYSLIB0003
    new SocketPermission(PermissionState.Unrestricted).Deny(); // warning SYSLIB0003
}

This is a compile-time only change. There is no run-time change from previous versions of .NET Core. Methods that perform no operation in .NET Core 2.x - 3.x will continue to perform no operation at run time in .NET 5 and later. Methods that throw PlatformNotSupportedException in .NET Core 2.x - 3.x will continue to throw a PlatformNotSupportedException at run time in .NET 5 and later.

Reason for change

Code access security (CAS) is an unsupported legacy technology. The infrastructure to enable CAS exists only in .NET Framework 2.x - 4.x, but is deprecated and not receiving servicing or security fixes.

Due to CAS's deprecation, the supporting infrastructure was not brought forward to .NET Core or .NET 5+. However, the APIs were brought forward so that apps could cross-compile against .NET Framework and .NET Core. This led to "fail open" scenarios, where some CAS-related APIs exist and are callable but perform no action at run time. This can lead to security issues for components that expect the runtime to honor CAS-related attributes or programmatic API calls. To better communicate that the runtime doesn't respect these attributes or APIs, we have obsoleted the majority of them in .NET 5.0.

Version introduced

5.0

  • If you're asserting any security permission, remove the attribute or call that asserts the permission.

    // REMOVE the attribute below.
    [SecurityPermission(SecurityAction.Assert, ControlThread = true)]
    public void DoSomething()
    {
    }
    
    public void DoAssert()
    {
        // REMOVE the line below.
        new SecurityPermission(SecurityPermissionFlag.ControlThread).Assert();
    }
    
  • If you're denying or restricting (via PermitOnly) any permission, contact your security advisor. Because CAS attributes are not honored by the .NET 5+ runtime, your application could have a security hole if it incorrectly relies on the CAS infrastructure to restrict access to these methods.

    // REVIEW the attribute below; could indicate security vulnerability.
    [SecurityPermission(SecurityAction.Deny, ControlThread = true)]
    public void DoSomething()
    {
    }
    
    public void DoPermitOnly()
    {
        // REVIEW the line below; could indicate security vulnerability.
        new SecurityPermission(SecurityPermissionFlag.ControlThread).PermitOnly();
    }
    
  • If you're demanding any permission (except PrincipalPermission), remove the demand. All demands will succeed at run time.

    // REMOVE the attribute below; it will always succeed.
    [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
    public void DoSomething()
    {
    }
    
    public void DoDemand()
    {
        // REMOVE the line below; it will always succeed.
        new SecurityPermission(SecurityPermissionFlag.ControlThread).Demand();
    }
    
  • If you're demanding PrincipalPermission, consult the guidance for PrincipalPermissionAttribute is obsolete as error. That guidance applies for both PrincipalPermission and PrincipalPermissionAttribute.

  • If you absolutely must disable these warnings (which is not recommended), you can suppress the SYSLIB0003 warning in code.

    #pragma warning disable SYSLIB0003 // disable the warning
    [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
    #pragma warning restore SYSLIB0003 // re-enable the warning
    public void DoSomething()
    {
    }
    
    public void DoDemand()
    {
    #pragma warning disable SYSLIB0003 // disable the warning
        new SecurityPermission(SecurityPermissionFlag.ControlThread).Demand();
    #pragma warning restore SYSLIB0003 // re-enable the warning
    }
    

    You can also suppress the warning in your project file. Doing so disables the warning for all source files within the project.

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>net5.0</TargetFramework>
        <!-- NoWarn below suppresses SYSLIB0003 project-wide -->
        <NoWarn>$(NoWarn);SYSLIB0003</NoWarn>
      </PropertyGroup>
    </Project>
    

    Note

    Suppressing SYSLIB0003 disables only the CAS-related obsoletion warnings. It does not disable any other warnings or change the behavior of the .NET 5+ runtime.

  • Security

Affected APIs