CA2117: APTCA 형식은 APTCA 기본 형식만 확장해야 합니다.

항목
RuleId CA2117
범주 Microsoft.Security
주요 변경 내용 주요 변경

원인

System.Security.AllowPartiallyTrustedCallersAttribute 특성이 있는 어셈블리의 public 또는 protected 형식이 해당 특성이 없는 어셈블리에서 선언된 형식에서 상속받습니다.

참고 항목

이 규칙은 더 이상 사용되지 않습니다. 자세한 내용은 사용되지 않는 규칙을 참조하세요.

규칙 설명

기본적으로 강력한 이름의 어셈블리에 있는 public 또는 protected 형식은 완전 신뢰를 위한 InheritanceDemand로 암시적으로 보호됩니다. AllowPartiallyTrustedCallersAttribute(APTCA) 특성으로 표시된 강력한 이름의 어셈블리에는 이 보호가 없습니다. 이 특성은 상속 요청을 사용하지 않도록 설정합니다. 상속 요청 없이 어셈블리에서 선언된 노출 형식은 완전 신뢰가 없는 형식이 상속받을 수 있습니다.

완전히 신뢰할 수 있는 어셈블리에 APTCA 특성이 있고 어셈블리의 형식이 부분적으로 신뢰할 수 있는 호출자를 허용하지 않는 형식에서 상속받는 경우 보안 익스플로잇이 가능합니다. 두 형식 T1T2가 다음 조건을 충족하는 경우 악성 호출자는 T1 형식을 사용하여 T2를 보호하는 암시적 완전 신뢰 상속 요청을 무시할 수 있습니다.

  • T1은 APTCA 특성이 있는, 완전히 신뢰할 수 있는 어셈블리에서 선언된 public 형식입니다.

  • T1은 어셈블리 외부의 T2 형식에서 상속받습니다.

  • T2 어셈블리에는 APTCA 특성이 없으므로 부분적으로 신뢰할 수 있는 어셈블리의 형식이 상속받을 수 없어야 합니다.

부분적으로 신뢰할 수 있는 X 형식이 T1에서 상속받을 수 있으므로 T2에서 선언된 상속받은 멤버에 액세스할 수 있습니다. T2에는 APTCA 특성이 없으므로 직접 실행 파생 형식(T1)이 완전 신뢰를 위한 상속 요청을 충족해야 합니다. T1에는 완전 신뢰가 있으므로 이 검사를 충족합니다. X가 신뢰할 수 없는 서브클래싱으로부터 T2를 보호하는 상속 요청을 충족하는 데 참여하지 않으므로 보안상 위험합니다. 이런 이유로 APTCA 특성이 있는 형식은 해당 특성이 없는 형식을 확장해서는 안 됩니다.

보다 일반적인 또 다른 보안 문제는 파생 형식(T1)이 프로그래머 오류를 통해 완전 신뢰가 필요한 형식(T2)에서 보호된 멤버를 노출할 수 있다는 것입니다. 노출이 발생하면 신뢰할 수 없는 호출자가 완전히 신뢰할 수 있는 형식에만 제공되어야 하는 정보에 액세스할 수 있게 됩니다.

위반 문제를 해결하는 방법

위반에서 보고된 형식이 APTCA 특성이 필요 없는 어셈블리에 있는 경우 형식을 제거합니다.

APTCA 특성이 필요한 경우 완전 신뢰를 위한 상속 요청을 형식에 추가합니다. 상속 요청은 신뢰할 수 없는 형식이 상속받을 수 없도록 방지합니다.

위반에서 보고된 기본 형식의 어셈블리에 APTCA 특성을 추가하여 위반 문제를 해결할 수 있습니다. 그 전에 어셈블리의 모든 코드와 어셈블리에 종속된 모든 코드의 보안을 집중적으로 검토해야 합니다.

경고를 표시하지 않는 경우

이 규칙의 경고를 안전하게 표시하지 않으려면 형식에서 노출하는 보호된 멤버를 통해 직접 또는 간접적으로 신뢰할 수 없는 호출자가 안전하지 않은 방식으로 사용될 수 있는 중요한 정보, 작업 또는 리소스에 액세스할 수 없도록 해야 합니다.

예시

다음 예제에서는 어셈블리 2개와 테스트 애플리케이션을 사용하여 이 규칙으로 검색된 보안 취약성을 보여 줍니다. 첫 번째 어셈블리에는 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 메서드만 호출해야 합니다.

참고 항목