Share via


CA2107: Deny と PermitOnly の用法を再確認します

Item [値]
規則 ID CA2107
カテゴリ Microsoft.Security
互換性に影響する変更点 あり

原因

メソッドに、セキュリティ アクションとして PermitOnly または Deny を指定するセキュリティ チェックが含まれています。

Note

このルールは非推奨とされました。 詳細については、「非推奨の規則」を参照してください。

規則の説明

System.Security.CodeAccessPermission.Deny セキュリティ アクションは、.NET のセキュリティについて高度な知識を持っている場合にのみ使用してください。 コードにこのセキュリティ アクションを使用する場合、セキュリティを再確認する必要があります。

Deny を指定すると、セキュリティ要求に対する応答で発生するスタック ウォークの既定の動作が変更されます。 これを利用すると、呼び出し履歴内の呼び出し元の実際のアクセス許可にかかわらず、拒否するメソッドの有効期間中に付与してはいけないアクセス許可を指定できます。 スタック ウォークで、Deny によってセキュリティで保護されたメソッドが検出された場合、要求されたアクセス許可が、拒否されたアクセス許可に含まれていると、スタック ウォークが失敗します。 PermitOnly を指定すると、スタック ウォークの既定の動作も変更されます。 これにより、コードでは、呼び出し元のアクセス許可にかかわらず、付与可能なアクセス許可のみを指定できます。 スタック ウォークで、PermitOnly によってセキュリティで保護されたメソッドが検出された場合、要求されたアクセス許可が、PermitOnly によって指定されたアクセス許可に含まれていないと、スタック ウォークが失敗します。

これらのアクションに依存するコードは、有用性が限られていて動作が理解しにくいため、セキュリティの脆弱性について慎重に評価する必要があります。 次の点について検討してください。

  • リンク確認要求は、Deny や PermitOnly の影響を受けません。

  • スタック ウォークを発生させる要求と同じスタック フレーム内で Deny または PermitOnly が発生する場合、セキュリティ アクションは無効です。

  • パスベースのアクセス許可を作成するために使用される値は、通常、複数の方法で指定できます。 1 つの形式のパスへのアクセスを拒否しても、すべての形式に対するアクセスが拒否されるわけではありません。 たとえば、ファイル共有 \\Server\Share がネットワーク ドライブ X: にマップされている場合、共有上のファイルへのアクセスを拒否するには、\\Server\Share\File、X:\File、およびそのファイルにアクセスするその他のすべてのパスを拒否する必要があります。

  • System.Security.CodeAccessPermission.Assert を使用すると、Deny または PermitOnly に到達する前にスタック ウォークを終了できます。

  • Deny による何らかの影響がある場合 (つまり、呼び出し元が、Deny によってブロックされるアクセス許可を持っている場合)、呼び出し元は、保護されているリソースに直接アクセスして、Deny を回避することができます。 同様に、拒否されるアクセス許可が呼び出し元にない場合、スタック ウォークは Deny がなくても失敗します。

違反の修正方法

これらのセキュリティ アクションのどれを使用しても違反が発生します。 違反を修正するには、これらのセキュリティ アクションを使用しないでください。

どのようなときに警告を抑制するか

この規則による警告は、セキュリティ レビューの完了後にのみ抑制してください。

例 1

次の例は、Deny に関するいくつかの制限を示しています。 ライブラリには 2 つのメソッドがあるクラスが含まれています。これらのメソッドは、それらを保護するセキュリティ要求以外は同一です。

using System.Security;
using System.Security.Permissions;
using System;

namespace SecurityRulesLibrary
{
   public  class SomeSecuredMethods
   {
    
      // Demand immediate caller has suitable permission
      // before revealing sensitive data.
      [EnvironmentPermissionAttribute(SecurityAction.LinkDemand,
          Read="COMPUTERNAME;USERNAME;USERDOMAIN")]

      public static void MethodProtectedByLinkDemand()
      {
         Console.Write("LinkDemand: ");
      }

      [EnvironmentPermissionAttribute(SecurityAction.Demand,
          Read="COMPUTERNAME;USERNAME;USERDOMAIN")]

      public static void MethodProtectedByDemand()
      {
         Console.Write("Demand: ");
      }
   }
}

例 2

次のアプリケーションは、ライブラリの保護されているメソッドに対する Deny の影響を示しています。

using System.Security;
using System.Security.Permissions;
using System;
using SecurityRulesLibrary;

namespace TestSecurityLibrary
{
    // Violates rule: ReviewDenyAndPermitOnlyUsage.
   public class TestPermitAndDeny
   {
      public static void TestAssertAndDeny()
      {
         EnvironmentPermission envPermission = new EnvironmentPermission(
               EnvironmentPermissionAccess.Read,
               "COMPUTERNAME;USERNAME;USERDOMAIN");
         envPermission.Assert();
         try
         {
            SomeSecuredMethods.MethodProtectedByDemand();
            Console.WriteLine(
               "Caller's Deny has no effect on Demand " + 
               "with the asserted permission.");

            SomeSecuredMethods.MethodProtectedByLinkDemand();
            Console.WriteLine(
               "Caller's Deny has no effect on LinkDemand " + 
               "with the asserted permission.");
         }
         catch (SecurityException e)
         {
            Console.WriteLine(
               "Caller's Deny protected the library.{0}", e);
         }
      }

      public static void TestDenyAndLinkDemand()
      {
         try
         {
            SomeSecuredMethods.MethodProtectedByLinkDemand();
            Console.WriteLine(
               "Caller's Deny has no effect with " +
               "LinkDemand-protected code.");
         }
         catch (SecurityException e)
         {
            Console.WriteLine(
               "Caller's Deny protected the library.{0}",e);
         }
      }
         
      public static void Main()
      {
         EnvironmentPermission envPermission = new EnvironmentPermission(
            EnvironmentPermissionAccess.Read,
            "COMPUTERNAME;USERNAME;USERDOMAIN");
         envPermission.Deny();

         //Test Deny and Assert interaction for LinkDemands and Demands.
         TestAssertAndDeny();

         //Test Deny's effects on code in different stack frame. 
         TestDenyAndLinkDemand();

         //Test Deny's effect on code in same frame as deny.
         try
         {
            SomeSecuredMethods.MethodProtectedByLinkDemand();
            Console.WriteLine(
               "This Deny has no effect with LinkDemand-protected code.");
         }
         catch (SecurityException e)
         {
            Console.WriteLine("This Deny protected the library.{0}",e);
         }
      }
   }
}

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

Demand: Caller's Deny has no effect on Demand with the asserted permission.
LinkDemand: Caller's Deny has no effect on LinkDemand with the asserted permission.
LinkDemand: Caller's Deny has no effect with LinkDemand-protected code.
LinkDemand: This Deny has no effect with LinkDemand-protected code.

関連項目