Demand と LinkDemand
更新 : 2007 年 11 月
宣言セキュリティには 2 種類のセキュリティ チェックがあり、似ていますが、チェック方法はかなり異なります。選択を誤るとセキュリティの脆弱性やパフォーマンスの低下を招くことがあるため、両方の形式について理解する必要があります。詳細については、「セキュリティ確認要求」を参照してください。
宣言セキュリティには、次のセキュリティ チェックがあります。
Demand は、コード アクセス セキュリティのスタック ウォークを指定します。スタック上のすべての呼び出し元は、チェックを通過するためのアクセス許可または ID が必要です。スタックには呼び出しごとに異なる呼び出し元が含まれるため、Demand は呼び出しごとに発生します。メソッドを繰り返し呼び出すと、呼び出しごとにセキュリティ チェックが発生します。Demand は、おとり攻撃を効果的に防御します。承認されていないコードが侵入を試みると、検出されます。
LinkDemand は Just-In-Time (JIT) コンパイル時に発生し、直接の呼び出し元だけをチェックします。このセキュリティ チェックは呼び出し元の呼び出し元はチェックしません。このチェックの通過後は、呼び出し元が何回呼び出しを実行しても、これ以上のセキュリティ オーバーヘッドはありません。ただし、おとり攻撃に対する防御能力もありません。LinkDemand を使用すると、テストを通過し、作成したコードを参照できるコードは、悪意のあるコードが承認済みコードを使用して呼び出しを行うことを許してしまうため、セキュリティが破壊される可能性があります。このため、少しでも脆弱性がある場合は、LinkDemand を使用しないでください。
LinkDemand を使用する場合の各種の予防措置は、個別にプログラミングする必要があります。セキュリティ システム側では、それらの措置の強制的な実行をサポートします。どのようなミスも、セキュリティを脆弱化します。作成したコードを使用する、承認されたすべてのコードは、次の措置を行うことによって、追加セキュリティを実装する責任があります。
呼び出し元のコードがクラスまたはアセンブリにアクセスするのを制限します。
呼び出し先のコードで実行されているセキュリティ チェックを呼び出し元コードにも設定し、呼び出し元の側の責任で実行されるようにします。たとえば、SecurityPermission に UnmanagedCode フラグが設定されている LinkDemand で保護されているメソッドを呼び出すコードを記述する場合は、呼び出し元のメソッドもこのアクセス許可の LinkDemand (または、より強力な Demand) を実行する必要があります。ただし、記述するコード内に他のセキュリティ保護機構 (Demand など) があり、安全が確実である場合だけは、LinkDemand で保護されたメソッドをコード内で使用できます。この例外的なケースでは、呼び出し側で、基になるコードでのセキュリティの脆弱性に対処する必要があります。
呼び出し元のコードが、呼び出し先のコードに成り代わって、保護されているコードを呼び出すことがないようにしてください。つまり、呼び出し元は承認されたコードに対して、保護されているコードに特定のパラメータを渡したり、結果を送り返させたりすることを強制できません。
インターフェイスとリンク確認要求
LinkDemand を指定した仮想のメソッド、プロパティ、またはイベントは、基本クラスのメソッドをオーバーライドする場合、オーバーライドされるメソッドがリンク確認要求されるように、基本クラスのメソッドにも同じ LinkDemand を指定する必要があります。悪意のあるコードが基本型にキャスト バックを行い、基本クラスのメソッドを呼び出す可能性があります。また、リンク確認要求は、アセンブリ レベルの属性 AllowPartiallyTrustedCallersAttribute を持たないアセンブリに暗黙に追加されます。
また、インターフェイス メソッドでリンク確認要求が指定されている場合は、メソッドの実装をリンク確認要求で保護するのは良い方法です。インターフェイスでリンク確認要求を使用するときは、次の点に注意が必要です。
AllowPartiallyTrustedCallersAttribute 属性もインターフェイスに適用されます。
リンク確認要求をインターフェイス部分に配置し、AllowPartiallyTrustedCallersAttribute 属性を使用する場合などに、選択的に特定のインターフェイスを部分的な信頼のコードから保護できます。
アセンブリ内でインターフェイスが定義され、これに AllowPartiallyTrustedCallersAttribute 属性が含まれない場合は、部分的な信頼のクラスにこのインターフェイスを実装できます。
インターフェイス メソッドを実装するクラスのパブリック メソッドに LinkDemand を指定する場合、そのインターフェイスにキャストし、メソッドを呼び出すときは LinkDemand は強制されません。この場合、インターフェイスに対してリンクしたため、インターフェイス上の LinkDemand だけが実行されます。
セキュリティの問題に関する次の項目を確認します。
インターフェイス メソッドにはリンク確認要求を明示的に指定します。リンク確認要求が適切な保護機能を与えることを確認します。前述のように、悪意のあるコードがキャストを使用して、リンク確認要求を回避できるかどうかを判断します。
リンク確認要求が適用された仮想メソッド。
このメソッドが実装する型とインターフェイス。これらは、一貫してリンク確認要求を使用する必要があります。