CA2117: APTCA-типы должны расширять только базовые APTCA-типы

Товар Значение
Идентификатор правила CA2117
Категория Microsoft.Security
Критическое изменение Критическое

Причина

Общедоступный или защищенный тип в сборке с System.Security.AllowPartiallyTrustedCallersAttribute атрибутом наследует от типа, объявленного в сборке, которая не имеет атрибута.

Примечание.

Это правило устарело. Дополнительные сведения см. в разделе "Устаревшие правила".

Описание правила

По умолчанию общедоступные или защищенные типы в сборках с строгими именами неявно защищаются в Наследуемом для полного доверия. Сборки с строгим именем, помеченные атрибутом AllowPartiallyTrustedCallersAttribute APTCA, не имеют этой защиты. Атрибут отключает требование наследования. Доступные типы, объявленные в сборке без требования наследования, наследуются типами, которые не имеют полного доверия.

Если атрибут APTCA присутствует в полностью доверенной сборке, а тип в сборке наследуется от типа, который не разрешает частично доверенных вызывающих объектов, возможно эксплойт безопасности. Если два типа T1 и T2 соответствуют следующим условиям, злоумышленники могут использовать тип T1 для обхода неявного требования к наследованию T2полного доверия, который защищает:

  • T1 — общедоступный тип, объявленный в полностью доверенной сборке с атрибутом APTCA.

  • T1 наследует от типа T2 вне сборки.

  • T2Сборка не имеет атрибута APTCA, поэтому не должна наследоваться типами в частично доверенных сборках.

Частично доверенный тип X может наследоваться, T1который предоставляет ему доступ к унаследованным членам, объявленным в T2. Поскольку T2 атрибут APTCA не имеет, его непосредственный производный тип (T1) должен соответствовать требованию наследования для полного доверия; T1 имеет полное доверие и поэтому удовлетворяет этому проверка. Риск безопасности заключается в том, что X не участвует в удовлетворении требования наследования, которое защищает T2 от недоверенного подкласса. По этой причине типы с атрибутом APTCA не должны расширять типы, у которых нет атрибута.

Другая проблема безопасности, и, возможно, более распространенная, заключается в том, что производный тип (T1) может, через ошибку программиста, предоставлять защищенные члены из типа, требующего полного доверия (T2). Когда эта уязвимость возникает, ненадежные вызывающие абоненты получают доступ к информации, которая должна быть доступна только для полностью доверенных типов.

Устранение нарушений

Если тип, сообщаемый нарушением, находится в сборке, которая не требует атрибута APTCA, удалите его.

Если атрибут APTCA является обязательным, добавьте требование наследования для полного доверия к типу. Требование наследования защищает от наследования ненадежными типами.

Можно устранить нарушение, добавив атрибут APTCA в сборки базовых типов, сообщаемых нарушением. Не выполняйте это без предварительного проведения интенсивной проверки безопасности всех кодов в сборках и всех кодах, зависящих от сборок.

Когда лучше отключить предупреждения

Чтобы безопасно отключить предупреждение из этого правила, необходимо убедиться, что защищенные члены, предоставляемые типом, не могут напрямую или косвенно разрешать ненадежным вызывающим пользователям доступ к конфиденциальной информации, операциям или ресурсам, которые могут использоваться разрушительным образом.

Пример

В следующем примере используются две сборки и тестовое приложение для иллюстрации уязвимости безопасности, обнаруженной этим правилом. Первая сборка не имеет атрибута APTCA и не должна наследоваться частично доверенными типами (представленными T2 в предыдущем обсуждении).

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

Вторая сборка, представленная T1 в предыдущем обсуждении, полностью доверяется и позволяет частично доверенным вызывающим абонентам.

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

Тип теста, представленный X в предыдущем обсуждении, находится в частично доверенной сборке.

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

В примере получается следующий вывод.

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: методы APTCA должны вызывать только методы APTCA

См. также