Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
GrabYourPitchforks opened this issue Oct 9, 2020 · 0 comments · Fixed by #21124
Closed
Assignees
Labels
breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 5 Work items for the .NET 5 release

Comments

@GrabYourPitchforks
Copy link
Member

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 5 Work items for the .NET 5 release
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants