CA2117: APTCA 型は APTCA 基本型のみを拡張することができます

TypeName

AptcaTypesShouldOnlyExtendAptcaBaseTypes

CheckId

CA2117

カテゴリ

Microsoft.Security

互換性に影響する変更点

あり

原因

System.Security.AllowPartiallyTrustedCallersAttribute 属性を持つアセンブリのパブリック型またはプロテクト型が、属性のないアセンブリで宣言された型から継承されています。

規則の説明

厳密な名前を持つアセンブリのパブリック型またはプロテクト型は、既定で、完全信頼の継承確認要求によって暗黙的に保護されます。 AllowPartiallyTrustedCallersAttribute (APTCA) 属性でマークされた厳密な名前のアセンブリには、この保護がありません。 この属性によって継承確認要求が無効になります。 そのため、公開する型は、完全信頼のない型によって継承できるアセンブリで宣言されます。

APTCA 属性が完全信頼のアセンブリにあり、アセンブリの型が部分信頼の呼び出し元を許可しない型から継承する場合、セキュリティ上の弱点になります。 T1 と T2 という 2 つの型が次の条件に適合する場合、悪意のある呼び出し元は、型 T1 を使用すると、T2 を保護する暗黙的な完全信頼の継承確認要求を省略できます。

  • T1 が、APTCA 属性を持つ完全信頼のアセンブリで宣言されたパブリック型である場合。

  • T1 がアセンブリ外の型 T2 から継承する場合。

  • T2 のアセンブリに APTCA 属性がないため、部分信頼のアセンブリの型から継承できない場合。

部分信頼の型 X は、T1 から継承できます。この場合、T2 で宣言された継承メンバーにアクセス権が付与されます。 T2 には APTCA 属性がないため、直接の派生型 (T1) は、完全信頼の継承確認要求に適合する必要があります。T1 には完全信頼があるため、このチェックに適合します。 X は、信頼されていないサブクラス化から T2 を保護する継承確認要求の適合に加わっていないため、セキュリティ上のリスクがあります。 そのため、APTCA 属性を持つ型によって、属性を持たない型を拡張しないでください。

別の、より一般的なセキュリティ問題を紹介します。プログラマのミスが原因で、派生型 (T1) によって、完全信頼を必要とする型 (T2) から保護されたメンバーが公開されることがあります。 この問題が発生すると、信頼関係のない呼び出し元が、完全信頼の型のみが使用できるはずの情報にアクセスできるようになります。

違反の修正方法

この違反がレポートされた型が APTCA 属性を必要としないアセンブリにある場合、削除します。

APTCA 属性が必要である場合、型に完全信頼の継承確認要求を追加します。 こうすることで、信頼関係のない型による継承を防ぐことができます。

この違反でレポートされた基本型のアセンブリに APTCA 属性を追加することで、違反を修正することもできます。 アセンブリ内のすべてのコードとそのアセンブリに依存するすべてのコードについて、必ず、徹底的にセキュリティを再確認してから、この方法を使用してください。

警告を抑制する状況

この規則による警告を安全に抑制するには、破壊的な方法で使用できる重要な情報、操作、またはリソースに信頼関係のない呼び出し元がアクセスすることを、使用している型で公開された保護されたメンバーによって直接的または間接的に許可しないようにします。

使用例

次の例では、2 つのアセンブリと 1 つのテスト アプリケーションを使用して、この規則で検出されるセキュリティ上の脆弱性を説明します。 1 つ目のアセンブリ (上記の説明では T2) に APTCA 属性はなく、部分信頼の型からは継承できません。

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

2 つ目のアセンブリ (上記の説明では 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());
        }
    }
}

この例を実行すると、次の出力が生成されます。

      

関連規則

CA2116: APTCA メソッドは APTCA メソッドのみを呼び出すことができます

参照

概念

安全なコーディングのガイドライン

部分的に信頼されているコードから .NET Framework アセンブリを呼び出すことができる

部分信頼コードからのライブラリの使用

継承確認要求