Поделиться через


Большинство API управления доступом для кода устарело

Большинство типов, связанных с управлением доступом для кода (CAS) в .NET, теперь являются устаревшими и приводят к созданию предупреждения. К ним относятся атрибуты управления доступом для кода, такие как SecurityPermissionAttribute, объекты разрешений CAS, например SocketPermission, производные от EvidenceBase типы, а также другие вспомогательные API.

Описание изменения

В .NET Framework версий с 2.x по 4.x атрибуты и API CAS могут влиять на выполнение кода, в том числе путем проверки успешности или неудачи проверки стека CAS.

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

В .NET Core версий с 2.x по 3.x среда выполнения не учитывает атрибуты CAS или API-интерфейсы CAS. Среда выполнения не учитывает атрибуты в записи метода, а большинство программных API-интерфейсов не оказывают никакого влияния.

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

Кроме того, программные вызовы разрешающих API (Assert) всегда завершаются успешно, а программные вызовы ограничивающих API (Deny, PermitOnly) всегда вызывают исключение во время выполнения. (PrincipalPermission является исключением из этого правила. См. раздел "Рекомендуемое действие " ниже.)

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();
}

В .NET 5 и более поздних версий большинство API, связанных с CAS, являются устаревшими и приводят к созданию предупреждения во время компиляции 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
}

Это изменение происходит только во время компиляции. Относительно предыдущих версий .NET Core во время выполнения нет никаких изменений. Методы, которые не выполняют никаких операций в .NET Core версий с 2.x по 3.x, также не выполняют никаких операций во время выполнения в .NET 5 и более поздних версий. Методы, которые создают исключение PlatformNotSupportedException в .NET Core версий с 2.x по 3.x, продолжают создавать исключение PlatformNotSupportedException во время выполнения в .NET 5 и более поздних версий.

Причина изменения

Устаревшая технология управления доступом для кода более не поддерживается. Инфраструктура, позволяющая включать управление доступом для кода, существует только в .NET Framework версий с 2.x по 4.x, но является устаревшей и больше не получает служебные исправления и исправления системы безопасности.

Поскольку технология CAS устарела, поддерживающая ее инфраструктура не была перенесена в .NET Core или .NET 5 и более поздних версий. Тем не менее, чтобы обеспечить возможность перекрестной компиляции приложений между .NET Framework и .NET Core, были перенесены API. Это привело к появлению сценариев, в которых некоторые связанные с CAS API-интерфейсы все еще существуют, но во время выполнения не выполняют никаких действий. Это может привести к проблемам с безопасностью для компонентов, которые ожидают, что среда выполнения должна учитывать атрибуты, связанные с CAS, или программные вызовы API. Чтобы более явно указать, что среда выполнения не учитывает эти атрибуты или API, в .NET 5.0 большинство из них помечены как устаревшие.

Представленные версии

5,0

  • Если вы утверждаете любое разрешение безопасности, удалите атрибут или вызов, который утверждает это разрешение.

    // REMOVE the attribute below.
    [SecurityPermission(SecurityAction.Assert, ControlThread = true)]
    public void DoSomething()
    {
    }
    
    public void DoAssert()
    {
        // REMOVE the line below.
        new SecurityPermission(SecurityPermissionFlag.ControlThread).Assert();
    }
    
  • Если вы запрещаете или ограничиваете любое разрешение (с помощью PermitOnly), обратитесь к своему консультанту по безопасности. Поскольку в .NET 5 и более поздних версий атрибуты CAS не учитываются средой выполнения, в системе безопасности вашего приложения может возникнуть брешь, связанная с неправильным использованием инфраструктуры CAS для ограничения доступа к этим методам.

    // 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();
    }
    
  • Если вам требуются какие-либо разрешения (кроме PrincipalPermission), удалите требование. Все требования будут исполнены во время выполнения.

    // 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();
    }
    
  • Если вам требуется PrincipalPermission, см. руководство PrincipalPermissionAttribute устарел и возвращает ошибку. Это руководство применимо как для PrincipalPermission, так и для PrincipalPermissionAttribute.

  • Если вам абсолютно необходимо отключить эти предупреждения, что не рекомендуется, можно отключить предупреждение SYSLIB0003 в коде.

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

    Это предупреждение также можно отключить в файле проекта. В таком случае предупреждение также будет отключено для всех исходных файлов в проекте.

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

    Примечание.

    В случае отключения SYSLIB0003 будет отключено только связанное с CAS предупреждение об устаревшем элементе. Это не отключает другие предупреждения и не меняет поведение среды выполнения в .NET 5 и более поздних версий.

  • Безопасность

Затронутые API