다음을 통해 공유


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

업데이트: 2007년 11월

TypeName

AptcaTypesShouldOnlyExtendAptcaBaseTypes

CheckId

CA2117

범주

Microsoft.Security

변경 수준

주요 변경

원인

System.Security.AllowPartiallyTrustedCallersAttribute 특성이 있는 어셈블리의 public 또는 protected 형식이 해당 특성이 없는 어셈블리에 선언되어 있는 형식으로부터 상속됩니다.

규칙 설명

기본적으로 강력한 이름이 있는 어셈블리의 public 또는 protected 형식은 완전 신뢰에 대한 상속 요청에 의해 암시적으로 보호됩니다. APTCA(AllowPartiallyTrustedCallersAttribute) 특성으로 표시된 강력한 이름의 어셈블리에는 이러한 보호 기능이 없습니다. 이 특성을 사용하면 상속 요청이 사용되지 않습니다. 이렇게 되면 어셈블리에 선언된 노출된 형식이 완전 신뢰가 없는 형식에서 상속될 수 있습니다.

완전 신뢰 어셈블리에 APTCA 특성이 있고 어셈블리의 형식이 부분 신뢰 호출자를 허용하지 않는 형식에서 상속되면 보안상 위험할 수 있습니다. 두 형식 T1과 T2가 다음 조건을 충족하면 악의적인 호출자가 T1 형식을 사용하여 T2를 보호하는 암시적인 완전 신뢰 상속 요청을 건너뛸 수 있습니다.

  • T1이 APTCA 특성을 가진 완전 신뢰 어셈블리에 선언된 public 형식입니다.

  • T1이 해당 어셈블리 외부에 있는 T2 형식에서 상속됩니다.

  • T2의 어셈블리에 APTCA 특성이 없으므로 부분 신뢰 어셈블리의 형식에서 상속될 수 없습니다.

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

이보다 더 자주 발생할 수 있는 다른 보안 문제는 파생 형식(T1)이 프로그래머의 실수로 인해 완전 신뢰가 필요한 형식(T2)에서 protected 멤버를 노출하는 것입니다. 이러한 문제가 발생하면 신뢰할 수 없는 호출자가 완전 신뢰 형식에서만 사용하도록 해야 하는 정보에 액세스할 수 있게 됩니다.

위반 문제를 해결하는 방법

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

APTCA 특성이 필요하면 해당 형식에 완전 신뢰에 대한 상속 요청을 추가합니다. 그러면 신뢰할 수 없는 형식에 상속되는 것을 막을 수 있습니다.

위반이 보고된 기본 형식의 어셈블리에 APTCA 특성을 추가하여 위반 문제를 해결할 수 있습니다. 어셈블리의 모든 코드 및 해당 어셈블리에 종속된 모든 코드의 보안 문제를 충분히 검토한 후 이 작업을 수행해야 합니다.

경고를 표시하지 않는 경우

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

예제

다음 예제에서는 두 개의 어셈블리와 테스트 응용 프로그램을 사용하여 이 규칙을 통해 감지되는 보안 문제를 보여 줍니다. 첫 번째 어셈블리에는 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!

관련 규칙

APTCA 메서드는 APTCA 메서드만 호출해야 합니다.

참고 항목

개념

AllowPartiallyTrustedCallersAttribute로 표시된 .NET Framework 어셈블리

부분 신뢰 코드에서 라이브러리 사용

상속 요청

기타 리소스

보안 코딩 지침