Skip to content

Breaking change notification: Most Code Access Security APIs are obsolete #21021

@GrabYourPitchforks

Description

@GrabYourPitchforks

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 (e.g., SecurityPermissionAttribute), CAS permission objects (e.g., SocketPermission), most EvidenceBase-derived types, and other supporting APIs.

Version introduced

.NET 5.0 RC1

Old behavior

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.

/* .NET Framework only */

// The attribute below 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.

/* .NET Core only */

// The .NET Core runtime ignores the below 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 runtime.

PrincipalPermission is an exception to this rule. See the section Recommended action below.

/* .NET Core only */

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

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

New behavior

Beginning with .NET 5.0, most CAS-related APIs are obsolete as warning. Using them will result in compile-time warnings.

/* .NET 5.0+ only */

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

This is a compile-time only change. There is no runtime change from previous versions of .NET Core. Method that performed no operation in .NET Core 2.x - 3.x will continue to perform no operation at runtime; methods that threw PlatformNotSupportedException in .NET Core 2.x - 3.x will continue to throw PlatformNotSupportedException at runtime.

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 the infrastructure is deprecated and is not receiving servicing or security fixes.

Due to CAS's deprecation, the runtime supporting infrastructure was not brought forward to .NET Core or .NET 5.0. See the document .NET Framework technologies unavailable on .NET Core for more information. However, the APIs were brought forward so that applications 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 runtime. This can lead to security issues for components which expect the runtime to honor CAS-related attributes or programmatic API calls. To better communicate that the runtime does not respect these attributes or APIs, we have obsoleted the majority of them in .NET 5.0.

Recommended action

If you are asserting any security permission, remove the attribute or call which 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 are denying or restricting (via PermitOnly) any permission, contact your security advisor. Because CAS attributes are not honored by the .NET 5.0+ runtime, your application could have a security hole if it incorrectly relies on the CAS infrastructure restricting 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 are demanding any permission (except PrincipalPermision), remove the demand. All demands will succeed at runtime.

// 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 are demanding PrincipalPermission, consult the guidance in the Recommended action section at https://aka.ms/dotnet-warnings/SYSLIB0002. That guidance applies both for PrincipalPermission and for PrincipalPermissionAttribute.

If you absolutely must disable these warnings (not recommended), you can suppress the SYSLIB0003 warning in code, as shown below.

#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
}

The warning can also be suppressed within the .csproj. Doing so will disable the warning for all source files within the project.

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

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

Category

  • Core .NET libraries

Affected APIs


Issue metadata

  • Issue type: breaking-change

Metadata

Metadata

Assignees

Labels

🏁 Release: .NET 5Work items for the .NET 5 releasebreaking-changeIndicates a .NET Core breaking change

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions