Share via


CA2117: I tipi APTCA devono estendere solo tipi di base APTCA

Articolo Valore
ID regola CA2117
Category Microsoft.Security
Modifica Interruzione

Causa

Un tipo pubblico o protetto in un assembly con l'attributo System.Security.AllowPartiallyTrustedCallersAttribute eredita da un tipo dichiarato in un assembly che non dispone dell'attributo .

Nota

Questa regola è stata deprecata. Per altre informazioni, vedere Regole deprecate.

Descrizione regola

Per impostazione predefinita, i tipi pubblici o protetti negli assembly con nomi sicuri vengono protetti in modo implicito da un oggetto InheritanceDemand per l'attendibilità totale. Gli assembly con nome sicuro contrassegnati con l'attributo AllowPartiallyTrustedCallersAttribute APTCA non dispongono di questa protezione. L'attributo disabilita la richiesta di ereditarietà. I tipi esposti dichiarati in un assembly senza una richiesta di ereditarietà sono ereditabili da tipi che non hanno attendibilità totale.

Quando l'attributo APTCA è presente in un assembly completamente attendibile e un tipo nell'assembly eredita da un tipo che non consente chiamanti parzialmente attendibili, è possibile un exploit di sicurezza. Se due tipi T1 e T2 soddisfano le condizioni seguenti, i chiamanti malintenzionati possono usare il tipo T1 per ignorare la richiesta implicita di ereditarietà dell'attendibilità completa che protegge T2:

  • T1 è un tipo pubblico dichiarato in un assembly completamente attendibile con l'attributo APTCA.

  • T1 eredita da un tipo T2 all'esterno dell'assembly.

  • T2L'assembly di non dispone dell'attributo APTCA e pertanto non deve essere ereditabile dai tipi in assembly parzialmente attendibili.

Un tipo X parzialmente attendibile può ereditare da T1, che consente l'accesso ai membri ereditati dichiarati in T2. Poiché T2 non dispone dell'attributo APTCA, il tipo derivato immediato (T1) deve soddisfare una richiesta di ereditarietà per l'attendibilità totale; T1 ha attendibilità completa e pertanto soddisfa questo controllo. Il rischio di sicurezza è dovuto X al fatto che non partecipa a soddisfare la richiesta di ereditarietà che protegge T2 dalla sottoclasse non attendibile. Per questo motivo, i tipi con l'attributo APTCA non devono estendere i tipi che non dispongono dell'attributo .

Un altro problema di sicurezza, e forse uno più comune, è che il tipo derivato (T1) può, tramite errore programmatore, esporre membri protetti dal tipo che richiede l'attendibilità completa (T2). Quando si verifica questa esposizione, i chiamanti non attendibili ottengono l'accesso alle informazioni che devono essere disponibili solo per i tipi completamente attendibili.

Come correggere le violazioni

Se il tipo segnalato dalla violazione si trova in un assembly che non richiede l'attributo APTCA, rimuoverlo.

Se l'attributo APTCA è obbligatorio, aggiungere una richiesta di ereditarietà per il trust completo al tipo. La richiesta di ereditarietà protegge dall'ereditarietà da tipi non attendibili.

È possibile correggere una violazione aggiungendo l'attributo APTCA agli assembly dei tipi di base segnalati dalla violazione. Non eseguire questa operazione senza prima eseguire una revisione intensiva della sicurezza di tutto il codice negli assembly e tutto il codice che dipende dagli assembly.

Quando eliminare gli avvisi

Per eliminare in modo sicuro un avviso da questa regola, è necessario assicurarsi che i membri protetti esposti dal tipo non consentano direttamente o indirettamente ai chiamanti non attendibili di accedere a informazioni riservate, operazioni o risorse che possono essere usate in modo distruttivo.

Esempio

Nell'esempio seguente vengono usati due assembly e un'applicazione di test per illustrare la vulnerabilità di sicurezza rilevata da questa regola. Il primo assembly non ha l'attributo APTCA e non deve essere ereditabile da tipi parzialmente attendibili (rappresentati dalla T2 discussione precedente).

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

Il secondo assembly, rappresentato da T1 nella discussione precedente, è completamente attendibile e consente chiamanti parzialmente attendibili.

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

Il tipo di test, rappresentato da X nella discussione precedente, si trova in un assembly parzialmente attendibile.

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

Nell'esempio viene prodotto l'output seguente:

Meet at the shady glen 2/22/2003 12:00:00 AM!
From Test: sunny meadow
Meet at the sunny meadow 2/22/2003 12:00:00 AM!

CA2116: I metodi APTCA devono chiamare solo metodi APTCA

Vedi anche