CA2117: Tipos APTCA só devem estender tipos básicos de APTCA

TypeName

AptcaTypesShouldOnlyExtendAptcaBaseTypes

CheckId

CA2117

<strong>Categoria</strong>

Microsoft.Security

Alteração significativa

Quebrando

Causa

Um tipo de público ou protegido em um assembly com o System.Security.AllowPartiallyTrustedCallersAttribute atributo herda a partir de um tipo declarado em um assembly que não tem o atributo.

Descrição da regra

Por padrão, os tipos de públicos ou protegidos em assemblys com nomes fortes implicitamente são protegidos por um Demandas de herança para confiança total. Assemblies de nomes fortes são marcados com o AllowPartiallyTrustedCallersAttribute atributo (APTCA) não possuem proteção. O atributo desativa a demanda de herança. Isso torna expostos tipos declarados no assembly herdados por tipos que não têm confiança total.

Quando o atributo APTCA está presente em um assembly totalmente confiável e um tipo no assembly herda a partir de um tipo que não permite chamadores parcialmente confiáveis, é possível a uma exploração de segurança. Se os dois tipos de T1 e T2 atender as seguintes condições, chamadores mal-intencionados podem usar o tipo de T1 para ignorar a demanda de herança implícita de confiança total que protege T2:

  • T1um tipo público é declarado em um assembly totalmente confiável que possui o atributo APTCA.

  • T1herda a partir de um tipo de T2 fora do assembly.

  • T2do assembly não tem o atributo APTCA e, portanto, não deve ser herdada por tipos em assemblies parcialmente confiáveis.

Um tipo parcialmente confiável X pode herdar de T1, que oferece acesso a membros herdados declarado em T2. Porque T2 não tem o atributo APTCA, seu tipo derivado de imediato (T1) deve satisfazer uma demanda de herança de confiança total; T1tem a confiança total e, portanto, satisfaz essa verificação. O risco de segurança é porque X não participa de satisfazer a demanda de herança que protege T2 de subclassificação não confiáveis. Por esse motivo, os tipos com o atributo APTCA não devem estender tipos que não possuem o atributo.

Outro problema de segurança e talvez um nome mais comum é que o tipo derivado (T1) podem, por meio de erro do programador expor membros protegidos do tipo que requer confiança total (T2). Quando isso ocorre, chamadores não confiáveis acessar informações que devem estar disponíveis somente aos tipos de totalmente confiáveis.

Como corrigir violações

Se o tipo relatado por violação em um assembly que não requer o atributo APTCA, removê-lo.

Se o atributo APTCA for necessário, adicione uma demanda de herança de confiança total para o tipo. Isso protege contra herança pelos tipos de não confiáveis.

É possível corrigir uma violação, adicionando o atributo APTCA aos assemblies tipos base relatado por violação. Não faça isso sem primeiro Conduzindo uma revisão de segurança de uso intensivo de todo o código que depende de assemblies e de todo o código nos assemblies do.

Quando suprimir avisos

Para suprimir com segurança um aviso da regra, você deve garantir que membros protegidos expostos pelo seu tipo não direta ou indiretamente permitem chamadores não confiáveis acessar informações confidenciais, operações ou recursos que podem ser usados de maneira destrutiva.

Exemplo

O exemplo a seguir usa dois assemblies e um aplicativo de teste para ilustrar a vulnerabilidade de segurança detectada por esta regra. O primeiro conjunto não tem o atributo APTCA e não deve ser herdado por tipos parcialmente confiáveis (representado por T2 na discussão anterior).

using System;
using System.Security;
using System.Security.Permissions;
using System.Reflection;

// This code is compiled into a strong-named assembly
// that requires full trust. 

namespace AptcaTestLibrary
{
   public class ClassRequiringFullTrustWhenInherited
   {
      // This field should be overridable by fully trusted derived types.
      protected static string location = "shady glen";

      // A trusted type can see the data, but cannot change it.
      public virtual string TrustedLocation 
      {
         get 
         {
            return location;
         }
      }
   }
}

O segundo conjunto, representado por T1 na discussão anterior, é totalmente confiável e permite que os chamadores parcialmente confiáveis.

using System;
using System.Security;
using System.Security.Permissions;
using System.Reflection;

// This class is compiled into an assembly that executes with full 
// trust and allows partially trusted callers. 

// Violates rule: AptcaTypesShouldOnlyExtendAptcaBaseTypes.

namespace AptcaTestLibrary
{
   public class InheritAClassRequiringFullTrust: 
      ClassRequiringFullTrustWhenInherited
   {
      private DateTime meetingDay = DateTime.Parse("February 22 2003");

      public override string ToString() 
      {
         // Another error:
         // This method gives untrusted callers the value 
         // of TrustedLocation. This information should 
         // only be seen by trusted callers.
         string s = String.Format(
            "Meet at the {0} {1}!", 
            this.TrustedLocation, meetingDay.ToString());
         return s;
      }
   }
}

O tipo de teste, representado por X na discussão anterior, está em um assembly parcialmente confiável.

using System;
using AptcaTestLibrary;

// If this test application is run from the local machine, 
//  it gets full trust by default.
// Remove full trust.
[assembly: System.Security.Permissions.PermissionSetAttribute(
   System.Security.Permissions.SecurityAction.RequestRefuse, Name = "FullTrust")]

namespace TestSecLibrary
{
    class InheritFromAFullTrustDecendent : ClassRequiringFullTrust
    {
        public InheritFromAFullTrustDecendent()
        {
            // This constructor maliciously overwrites the protected 
            // static member in the fully trusted class.
            // Trusted types will now get the wrong information from 
            // the TrustedLocation property.
            InheritFromAFullTrustDecendent.location = "sunny meadow";
        }

        public override string ToString()
        {
            return InheritFromAFullTrustDecendent.location;
        }
    }

    class TestApctaInheritRule
    {
        public static void Main()
        {
            ClassRequiringFullTrust iclass =
               new ClassRequiringFullTrust();
            Console.WriteLine(iclass.ToString());

            // You cannot create a type that inherits from the full trust type
            // directly, but you can create a type that inherits from 
            // the APTCA type which in turn inherits from the full trust type.

            InheritFromAFullTrustDecendent inherit =
               new InheritFromAFullTrustDecendent();
            //Show the inherited protected member has changed.
            Console.WriteLine("From Test: {0}", inherit.ToString());

            // Trusted types now get the wrong information from 
            // the TrustedLocation property.
            Console.WriteLine(iclass.ToString());
        }
    }
}

O exemplo produz a seguinte saída.

      

Regras relacionadas

CA2116: Métodos APTCA só deverá chamar métodos APTCA

Consulte também

Conceitos

Diretrizes para Codificação Segura

.NET Framework Assemblies podem ser chamados pelo código parcialmente confiável

Usando bibliotecas de código parcialmente confiáveis

Demandas de herança