.NET Framework には、共通の中間言語 (CIL) を出力する 3 つの方法が用意されています。それぞれに独自のセキュリティの問題があります。
動的コードを生成する方法に関係なく、生成されたコードを実行するには、生成されたコードで使用される型とメソッドに必要なすべてのアクセス許可が必要です。
注
コードへの反映とコードの出力に必要なアクセス許可は、.NET Framework のリリースの成功に伴って変更されました。 この記事の後半の 「バージョン情報」を参照してください。
動的アセンブリ
動的アセンブリは、 AppDomain.DefineDynamicAssembly メソッドのオーバーロードを使用して作成されます。 このメソッドのほとんどのオーバーロードは、コンピューター全体のセキュリティ ポリシーが削除されるため、.NET Framework 4 では非推奨となっています。 残りのオーバーロードは、信頼レベルに関係なく、任意のコードで実行できます。 これらのオーバーロードは 2 つのグループに分類されます。動的アセンブリの作成時に適用する属性の一覧を指定するグループと、適用されない属性のリストを指定するグループです。 アセンブリの透過性モデルを指定しない場合は、作成時に SecurityRulesAttribute 属性を適用することで、透過性モデルが出力アセンブリから継承されます。
注
SetCustomAttribute メソッドを使用して、動的アセンブリの作成後に動的アセンブリに適用する属性は、アセンブリがディスクに保存されてメモリに再び読み込まれるまで有効になりません。
動的アセンブリ内のコードは、他のアセンブリの参照可能な型とメンバーにアクセスできます。
注
動的アセンブリでは、動的メソッドが非パブリック型およびメンバーにアクセスできるようにする ReflectionPermissionFlag.MemberAccess フラグと ReflectionPermissionFlag.RestrictedMemberAccess フラグは使用されません。
一時的な動的アセンブリはメモリ内に作成され、ディスクに保存されないため、ファイル アクセス許可は必要ありません。 動的アセンブリをディスクに保存するには、適切なフラグを使用して FileIOPermission する必要があります。
部分信頼コードからの動的アセンブリの生成
インターネットのアクセス許可を持つアセンブリが一時的な動的アセンブリを生成し、そのコードを実行できる条件を検討します。
動的アセンブリでは、他のアセンブリのパブリック型とメンバーのみが使用されます。
これらの型とメンバーによって要求されるアクセス許可は、部分的に信頼されたアセンブリの許可セットに含まれます。
アセンブリはディスクに保存されません。
デバッグ シンボルは生成されません。 (
Internet
およびLocalIntranet
アクセス許可セットには、必要なアクセス許可は含まれません)。
匿名でホストされる動的メソッド
匿名でホストされる動的メソッドは、関連付けられた型またはモジュール (DynamicMethodとDynamicMethod(String, Type, Type[])) を指定しない 2 つのDynamicMethod(String, Type, Type[], Boolean) コンストラクターを使用して作成されます。 これらのコンストラクターは、システム提供の完全に信頼されたセキュリティ透過的なアセンブリに動的メソッドを配置します。 これらのコンストラクターを使用したり、動的メソッドのコードを出力したりするために、アクセス許可は必要ありません。
代わりに、匿名でホストされる動的メソッドが作成されると、呼び出し履歴がキャプチャされます。 メソッドが構築されると、キャプチャされた呼び出し履歴に対してセキュリティ要求が行われます。
注
概念的には、メソッドの構築中に要求が行われます。 つまり、各 CIL 命令が出力されるときに要求を行うことができます。 現在の実装では、 DynamicMethod.CreateDelegate メソッドが呼び出されたとき、または Just-In-Time (JIT) コンパイラが呼び出されたときに、 CreateDelegateを呼び出さずにメソッドが呼び出されると、すべての要求が行われます。
アプリケーション ドメインで許可されている場合、匿名でホストされる動的メソッドは JIT 可視性チェックをスキップできます。次の制限に従います。匿名でホストされる動的メソッドによってアクセスされる非パブリック型とメンバーは、出力元の呼び出し履歴の許可セットと等しい (または、そのサブセットの) アセンブリ内に存在する必要があります。 この制限付き JIT 可視性チェックをスキップする機能は、アプリケーション ドメインが ReflectionPermission フラグを使用してReflectionPermissionFlag.RestrictedMemberAccessを許可する場合に有効になります。
メソッドでパブリック型とメンバーのみを使用する場合、構築中にアクセス許可は必要ありません。
JIT 可視性チェックをスキップすることを指定した場合、メソッドの構築時に行われる要求には、ReflectionPermission フラグを持つReflectionPermissionFlag.RestrictedMemberAccessと、アクセスされる非パブリック メンバーを含むアセンブリの許可セットが含まれます。
非パブリック メンバーの許可セットが考慮されるため、 ReflectionPermissionFlag.RestrictedMemberAccess 付与された部分的に信頼されたコードは、信頼されたアセンブリの非パブリック メンバーを実行して特権を昇格できません。
他の出力されるコードと同様に、動的メソッドを実行するには、動的メソッドが使用するメソッドによって要求されるすべてのアクセス許可が必要です。
匿名でホストされる動的メソッドをホストするシステム アセンブリでは、.NET Framework 4 より前の .NET Framework で使用されていた透過性モデルである SecurityRuleSet.Level1 透過性モデルが使用されます。
詳細については、DynamicMethod クラスを参照してください。
部分的に信頼されたコードから匿名でホストされる動的メソッドを生成する
インターネットアクセス許可を持つアセンブリが匿名でホストされる動的メソッドを生成し、それを実行できる条件を検討します。
動的メソッドでは、パブリック型とメンバーのみが使用されます。 その許可セットに ReflectionPermissionFlag.RestrictedMemberAccess が含まれている場合、発行アセンブリの許可セットと同等またはその一部の許可セットを持つ任意のアセンブリの非公開型やメンバーを使用することができます。
動的メソッドで使用されるすべての型とメンバーに必要なアクセス許可は、部分的に信頼されたアセンブリの許可セットに含まれます。
注
動的メソッドはデバッグ シンボルをサポートしていません。
既存のアセンブリに関連付けられている動的メソッド
動的メソッドを既存のアセンブリ内の型またはモジュールに関連付けるには、関連付けられている型またはモジュールを指定する DynamicMethod コンストラクターのいずれかを使用します。 動的メソッドを既存の型またはモジュールに関連付けることで、非パブリック型とメンバーに動的メソッドがアクセスできるため、これらのコンストラクターの呼び出しに必要なアクセス許可は異なります。
型に関連付けられている動的メソッドは、その型のすべてのメンバー 、プライベート メンバー、および関連付けられた型を含むアセンブリ内のすべての内部型とメンバーにアクセスできます。
モジュールに関連付けられている動的メソッドは、モジュール内のすべての
internal
型とメンバー (Visual Basic ではFriend
、共通言語ランタイム メタデータではassembly
) にアクセスできます。
さらに、JIT コンパイラの可視性チェックをスキップする機能を指定するコンストラクターを使用することもできます。 これにより、アクセス レベルに関係なく、すべてのアセンブリのすべての型とメンバーに動的メソッドがアクセスできます。
コンストラクターによって要求されるアクセス許可は、動的メソッドを指定するアクセス権の量によって異なります。
メソッドでパブリック型とメンバーのみを使用し、独自の型または独自のモジュールに関連付ける場合、アクセス許可は必要ありません。
JIT 可視性チェックをスキップすることを指定した場合、コンストラクターは ReflectionPermission フラグを使用してReflectionPermissionFlag.MemberAccessを要求します。
動的メソッドを別の型 (独自のアセンブリ内の別の型) に関連付ける場合、コンストラクターはReflectionPermission フラグとReflectionPermissionFlag.MemberAccessを要求し、SecurityPermission フラグでSecurityPermissionFlag.ControlEvidenceします。
動的メソッドを別のアセンブリの型またはモジュールに関連付ける場合、コンストラクターは、ReflectionPermission フラグを持つReflectionPermissionFlag.RestrictedMemberAccessと、もう一方のモジュールを含むアセンブリの許可セットの 2 つを要求します。 つまり、呼び出し履歴には、ターゲット モジュールの許可セット内のすべてのアクセス許可と ReflectionPermissionFlag.RestrictedMemberAccessが含まれている必要があります。
注
下位互換性のために、ターゲット許可セットとReflectionPermissionFlag.RestrictedMemberAccessの要求が失敗した場合、コンストラクターは SecurityPermission フラグを使用してSecurityPermissionFlag.ControlEvidenceを要求します。
この一覧の項目は、出力アセンブリの許可セットに関して説明されていますが、アプリケーション ドメインの境界を含む完全な呼び出し履歴に対して要求が行われていることに注意してください。
詳細については、DynamicMethod クラスを参照してください。
部分的に信頼されたコードから動的メソッドを生成する
注
部分的に信頼されたコードから動的メソッドを生成するには、 匿名でホストされる動的メソッドを使用することをお勧めします。
インターネットアクセス許可を持つアセンブリが動的メソッドを生成して実行できる条件を検討します。
動的メソッドは、それを出力するモジュールまたは型に関連付けられているか、その許可セットに ReflectionPermissionFlag.RestrictedMemberAccess が含まれており、その許可セットが出力アセンブリの許可セットと等しいアセンブリ内のモジュールに関連付けられているか、または出力アセンブリの許可セットのサブセットに関連付けられています。
動的メソッドでは、パブリック型とメンバーのみが使用されます。 その許可セットに ReflectionPermissionFlag.RestrictedMemberAccess が含まれており、その許可セットが出力アセンブリの許可セットまたはサブセットであるアセンブリ内のモジュールに関連付けられている場合は、関連付けられたモジュールで
internal
マークされた型とメンバー (Visual Basic ではFriend
、共通言語ランタイム メタデータのassembly
) を使用できます。動的メソッドによって使用されるすべての型とメンバーによって要求されるアクセス許可は、部分的に信頼されたアセンブリの許可セットに含まれます。
動的メソッドは、JIT 可視性チェックをスキップしません。
注
動的メソッドはデバッグ シンボルをサポートしていません。
バージョン情報
.NET Framework 4 以降では、コンピューター全体のセキュリティ ポリシーが削除され、セキュリティの透明性が既定の適用メカニズムになります。
.NET Framework 2.0 Service Pack 1 以降では、動的アセンブリと動的メソッドを出力するときに、ReflectionPermission フラグを使用したReflectionPermissionFlag.ReflectionEmitは不要になりました。 このフラグは、以前のすべてのバージョンの .NET Framework で必要です。
注
ReflectionPermission では、 ReflectionPermissionFlag.ReflectionEmit フラグが既定で FullTrust
および LocalIntranet
名前付きアクセス許可セットに含まれますが、 Internet
アクセス許可セットには含まれません。 そのため、以前のバージョンの .NET Framework では、ライブラリは、AssertのReflectionEmitを実行する場合にのみ、インターネットアクセス許可で使用できます。 このようなライブラリでは、コーディング エラーによってセキュリティホールが発生する可能性があるため、慎重なセキュリティ レビューが必要です。 .NET Framework 2.0 SP1 では、コードの生成は本質的に特権操作ではないため、セキュリティ要求を発行せずに部分信頼シナリオでコードを生成できます。 つまり、生成されたコードには、それを出力するアセンブリよりも多くのアクセス許可がありません。 これにより、コードを出力するライブラリはセキュリティを透過的にし、 ReflectionEmitをアサートする必要がなくなります。これにより、セキュリティで保護されたライブラリを記述するタスクが簡略化されます。
さらに、.NET Framework 2.0 SP1 では、部分的に信頼された動的メソッドから非パブリック型とメンバーにアクセスするための ReflectionPermissionFlag.RestrictedMemberAccess フラグが導入されています。 以前のバージョンの .NET Framework では、非パブリック型とメンバーにアクセスする動的メソッドに対して ReflectionPermissionFlag.MemberAccess フラグが必要です。これは、部分的に信頼されたコードに付与すべきでないアクセス許可です。
最後に、.NET Framework 2.0 SP1 では匿名でホストされるメソッドが導入されています。
型とメンバーに関する情報の取得
.NET Framework 2.0 以降では、非パブリック型とメンバーに関する情報を取得するためのアクセス許可は必要ありません。 リフレクションは、動的メソッドを出力するために必要な情報を取得するために使用されます。 たとえば、 MethodInfo オブジェクトはメソッド呼び出しを出力するために使用されます。 以前のバージョンの .NET Framework では、ReflectionPermission を ReflectionPermissionFlag.TypeInformation フラグと共に使用する必要があります。 詳細については、「 リフレクションのセキュリティに関する考慮事項」を参照してください。
こちらも参照ください
.NET