リフレクションに関するセキュリティ上の考慮事項Security Considerations for Reflection

リフレクションを使用すると、型とメンバーに関する情報を取得し、メンバーにアクセスできます (つまり、メソッドやコンストラクターの呼び出し、プロパティ値の取得と設定、イベント ハンドラーの追加と削除などを実行できます)。Reflection provides the ability to obtain information about types and members, and to access members (that is, to call methods and constructors, to get and set property values, to add and remove event handlers, and so on). リフレクションを使用した型とメンバーに関する情報の取得には、制限がありません。The use of reflection to obtain information about types and members is not restricted. すべてのコードで、次のタスクを実行するためにリフレクションを使用できます。All code can use reflection to perform the following tasks:

  • 型とメンバーを列挙し、そのメタデータを確認する。Enumerate types and members, and examine their metadata.

  • アセンブリとモジュールを列挙し、確認する。Enumerate and examine assemblies and modules.

これに対して、リフレクションを使用したメンバーへのアクセスには、制限があります。Using reflection to access members, by contrast, is subject to restrictions. .NET Framework 4 以降、リフレクションを使用してセキュリティ クリティカルなメンバーにアクセスできるのは、信頼されているコードだけです。Beginning with the .NET Framework 4, only trusted code can use reflection to access security-critical members. さらに、コンパイル済みコードに直接アクセスできない非パブリック メンバーに、リフレクションを使用してアクセスできるのも信頼されたコードだけです。Furthermore, only trusted code can use reflection to access nonpublic members that would not be directly accessible to compiled code. 最後に、セーフ クリティカルなメンバーにアクセスするリフレクションを使用するコードには、コンパイル済みコードと同様、セーフ クリティカル メンバーが要求するすべてのアクセス許可が必要です。Finally, code that uses reflection to access a safe-critical member must have whatever permissions the safe-critical member demands, just as with compiled code.

必要なアクセス許可がある場合、コードはリフレクションを使用して次の種類のアクセスを実行できます。Subject to necessary permissions, code can use reflection to perform the following kinds of access:

  • セキュリティ クリティカルではないをパブリック メンバーへのアクセス。Access public members that are not security-critical.

  • コンパイル済みコードにアクセスできる非パブリック メンバーへのアクセス (そのメンバーがセキュリティ クリティカルでない場合)。Access nonpublic members that would be accessible to compiled code, if those members are not security-critical. このような非パブリック メンバーの例を次に示します。Examples of such nonpublic members include:

    • 呼び出し元コードの基本クラスのプロテクト メンバー。Protected members of the calling code's base classes. (リフレクションの場合、これはファミリレベル アクセスと呼ばれます。)(In reflection, this is referred to as family-level access.)

    • 呼び出し元コードのアセンブリの internal メンバー (Visual Basic では Friend メンバー)internal members (Friend members in Visual Basic) in the calling code's assembly. (リフレクションの場合、これはアセンブリレベル アクセスと呼ばれます)。(In reflection, this is referred to as assembly-level access.)

    • 呼び出し元コードを含むクラスの他のインスタンスのプライベート メンバー。Private members of other instances of the class that contains the calling code.

たとえば、サンドボックス化されたアプリケーション ドメインで実行されるコードは、アプリケーション ドメインから追加のアクセス許可が付与されていない限り、この一覧に示したアクセスに限定されます。For example, code that is run in a sandboxed application domain is limited to the access described in this list, unless the application domain grants additional permissions.

.NET Framework 2.0 Service Pack 1 以降では、通常はアクセスできないメンバーにアクセスしようとすると、対象オブジェクトと ReflectionPermissionFlag.MemberAccess フラグが設定された ReflectionPermission の許可セットに対する要求が生成されます。Starting with the .NET Framework 2.0 Service Pack 1, attempting to access members that are normally inaccessible generates a demand for the grant set of the target object plus ReflectionPermission with the ReflectionPermissionFlag.MemberAccess flag. 完全な信頼で実行されているコード (コマンド ラインから起動されるアプリケーションのコードなど) には、必要とされるこれらのアクセス許可が常にあります。Code that is running with full trust (for example, code in an application that is launched from the command line) can always satisfy these permissions. (ただし、後で説明するように、セキュリティ クリティカルなメンバーにアクセスする場合は制限があります)。(This is subject to limitations in accessing security-critical members, as described later in this article.)

必要に応じて、サンドボックス化されたアプリケーション ドメインから、ReflectionPermissionFlag.MemberAccess フラグが設定された ReflectionPermission を付与できます。これについては、後半の「通常はアクセスできないメンバーへのアクセス」で説明します。Optionally, a sandboxed application domain can grant ReflectionPermission with the ReflectionPermissionFlag.MemberAccess flag, as described in the section Accessing Members That Are Normally Inaccessible, later in this article.

セキュリティ クリティカルなメンバーへのアクセスAccessing Security-Critical Members

メンバーは、SecurityCriticalAttribute が指定されている場合、SecurityCriticalAttribute が指定されている型に属する場合、またはセキュリティ クリティカルなアセンブリ内にある場合は、セキュリティ クリティカルです。A member is security-critical if it has the SecurityCriticalAttribute, if it belongs to a type that has the SecurityCriticalAttribute, or if it is in a security-critical assembly. .NET Framework 4 以降では、セキュリティ クリティカルなメンバーにアクセスする場合の規則は次のとおりです。Beginning with the .NET Framework 4, the rules for accessing security-critical members are as follows:

  • 透過的なコードでは、コードが完全に信頼されている場合でも、リフレクションを使用してセキュリティ クリティカルなメンバーにアクセスすることはできません。Transparent code cannot use reflection to access security-critical members, even if the code is fully trusted. MethodAccessExceptionFieldAccessException、または TypeAccessException がスローされます。A MethodAccessException, FieldAccessException, or TypeAccessException is thrown.

  • 部分信頼で実行されているコードは透過的として扱われます。Code that is running with partial trust is treated as transparent.

これらの規則は、セキュリティ クリティカルなメンバーにコンパイルされたコードから直接アクセスする場合でも、リフレクションを使用してアクセスする場合でも同じです。These rules are the same whether a security-critical member is accessed directly by compiled code, or accessed by using reflection.

コマンド ラインから実行されるアプリケーション コードは完全信頼で実行されます。Application code that is run from the command line runs with full trust. この場合、透過的とマークされていない限り、リフレクションを使用してセキュリティ クリティカルなメンバーにアクセスできます。As long as it is not marked as transparent, it can use reflection to access security-critical members. 同じコードが部分信頼で実行される場合 (サンドボックス化されたアプリケーション ドメイン内など)、セキュリティ クリティカル コードにアクセスできるかどうかは、アセンブリの信頼レベルによって決まります。アセンブリが厳密な名前を持ち、グローバル アセンブリ キャッシュにインストールされている場合は、信頼されたアセンブリとして、セキュリティ クリティカルなメンバーを呼び出すことができます。When the same code is run with partial trust (for example, in a sandboxed application domain) the assembly's trust level determines whether it can access security-critical code: If the assembly has a strong name and is installed in the global assembly cache, it is a trusted assembly and can call security-critical members. 信頼されない場合は、透過的とマークされていなくても透過的として扱われ、セキュリティ クリティカルなメンバーにはアクセスできません。If it is not trusted, it becomes transparent even though it was not marked as transparent, and it cannot access security-critical members.

.NET Framework 4 のセキュリティ モデルの詳細については、「.NET Framework におけるセキュリティの変更点」を参照してください。For more information about the security model in the .NET Framework 4, see Security Changes.

リフレクションと透過Reflection and Transparency

.NET Framework 4 以降では、型またはメンバーの透過度は、アセンブリの信頼レベルやアプリケーション ドメインの信頼レベルなど、複数の要素に基づいて共通言語ランタイムによって決定されます。Beginning with the .NET Framework 4, the common language runtime determines the transparency level of a type or member from several factors, including the trust level of the assembly and the trust level of the application domain. リフレクションには、型の透過度を確認できる IsSecurityCriticalIsSecuritySafeCriticalIsSecurityTransparent の各プロパティが用意されています。Reflection provides the IsSecurityCritical, IsSecuritySafeCritical, and IsSecurityTransparent properties to enable you to discover the transparency level of a type. これらのプロパティの有効な組み合わせを、次の表に示します。The following table shows the valid combinations of these properties.

セキュリティ レベルSecurity level IsSecurityCriticalIsSecurityCritical IsSecuritySafeCriticalIsSecuritySafeCritical IsSecurityTransparentIsSecurityTransparent
重大Critical true false false
セーフ クリティカルSafe-critical true true false
透明Transparent false false true

これらのプロパティを使用する方が、アセンブリとその型のセキュリティの注釈を調べたり、現在の信頼レベルを確認したり、ランタイムの規則を複製したりするより、はるかに簡単です。Using these properties is much simpler than examining the security annotations of an assembly and its types, checking the current trust level, and attempting to duplicate the runtime's rules. たとえば、同じ型でも、コマンド ラインから実行される場合はセキュリティ クリティカルとなり、サンドボックス化されたアプリケーション ドメインで実行される場合は透過的セキュリティとなります。For example, the same type can be security-critical when it is run from the command line, or security-transparent when it is run in a sandboxed application domain.

MethodBaseFieldInfoTypeBuilderMethodBuilderDynamicMethod の各クラスには、同様のプロパティがありますThere are similar properties on the MethodBase, FieldInfo, TypeBuilder, MethodBuilder, and DynamicMethod classes. (プロパティ アクセサーに適用されるプロパティの場合など、その他のリフレクションとリフレクション出力の抽象クラスでは、関連付けられたメソッドにセキュリティ属性が適用されます)。(For other reflection and reflection emit abstractions, security attributes are applied to the associated methods; for example, in the case of properties they are applied to the property accessors.)

通常はアクセスできないメンバーへのアクセスAccessing Members That Are Normally Inaccessible

リフレクションを使用して、共通言語ランタイムのアクセシビリティ規則によりアクセスできないメンバーを呼び出すには、次の 2 つのアクセス許可のどちらかをコードに許可する必要があります。To use reflection to invoke members that are inaccessible according to the accessibility rules of the common language runtime, your code must be granted one of two permissions:

  • コードから非パブリック メンバーを呼び出せるようにするには、ReflectionPermissionFlag.MemberAccess フラグが設定された ReflectionPermission をコードに与える必要があります。To allow code to invoke any nonpublic member:Your code must be granted ReflectionPermission with the ReflectionPermissionFlag.MemberAccess flag.

    注意

    既定で、インターネットを起源とするコードにこのアクセス許可を与えることは、セキュリティ ポリシーによって禁じられています。By default, security policy denies this permission to code that originates from the Internet. インターネットを起源とするコードには、このアクセス許可を絶対に与えないでください。This permission should never be granted to code that originates from the Internet.

  • 呼び出されるメンバーが格納されているアセンブリの許可セットが、呼び出し元のコードが格納されているアセンブリの許可セットと同じか、またはそのサブセットである場合に限り、コードから非パブリック メンバーを呼び出せるようにするには、ReflectionPermissionFlag.RestrictedMemberAccess フラグが設定された ReflectionPermission をコードに与える必要があります。To allow code to invoke any nonpublic member, as long as the grant set of the assembly that contains the invoked member is the same as, or a subset of, the grant set of the assembly that contains the invoking code: Your code must be granted ReflectionPermission with the ReflectionPermissionFlag.RestrictedMemberAccess flag.

たとえば、アプリケーション ドメインにインターネット アクセス許可を付与すると共に、ReflectionPermissionFlag.RestrictedMemberAccessReflectionPermission フラグを指定するとします。次に、A と B の 2 つのアセンブリを使用して、インターネット アプリケーションを実行します。For example, suppose you grant an application domain Internet permissions plus ReflectionPermission with the ReflectionPermissionFlag.RestrictedMemberAccess flag, and then run an Internet application with two assemblies, A and B.

  • アセンブリ B の許可セットには、アセンブリ A に付与されていないアクセス許可が含まれていないため、アセンブリ A でリフレクションを使用してアセンブリ B のプライベート メンバーにアクセスできます。Assembly A can use reflection to access private members of assembly B, because the grant set of assembly B does not include any permissions that A has not been granted.

  • アセンブリ A では、リフレクションを使用して mscorlib.dll などの .NET Framework アセンブリのプライベート メンバーにアクセスすることはできません。これは、mscorlib.dll が完全に信頼されており、アセンブリ A に付与されていないアクセス許可を持つためです。実行時にコード アクセス セキュリティによりスタックが走査されると、MemberAccessException がスローされます。Assembly A cannot use reflection to access private members of .NET Framework assemblies such as mscorlib.dll, because mscorlib.dll is fully trusted and therefore has permissions that have not been granted to assembly A. A MemberAccessException is thrown when code access security walks the stack at run time.

シリアル化Serialization

シリアル化の目的で、SecurityPermissionSecurityPermissionAttribute.SerializationFormatter フラグを指定することで、アクセシビリティに関係なく、シリアル化が可能な型のメンバーを取得および設定できるようになります。For serialization, SecurityPermission with the SecurityPermissionAttribute.SerializationFormatter flag provides the ability to get and set members of serializable types, regardless of accessibility. このアクセス許可があると、コードで、インスタンスのプライベート状態を探索したり、変更したりできます。This permission enables code to discover and change the private state of an instance. 型に対して適切なアクセス許可が与えられていると同時に、メタデータ内でシリアル化可能としてマークされている必要があります。(In addition to being granted the appropriate permissions, the type must be marked as serializable in metadata.)

MethodInfo 型のパラメーターParameters of Type MethodInfo

特に、信頼されているコードには、MethodInfo パラメーターを受け取るパブリック メンバーを記述しないでください。Avoid writing public members that take MethodInfo parameters, especially for trusted code. このようなメンバーは、悪意のあるコードの攻撃を受けやすい場合があります。Such members might be more vulnerable to malicious code. たとえば、信頼性の高いコード内で、MethodInfo パラメーターを受け取るパブリック メンバーの場合を考えてみましょう。For example, consider a public member in highly trusted code that takes a MethodInfo parameter. このパブリック メンバーが、渡されたパラメーターに対して間接的に Invoke メソッドを呼び出すとします。Assume that the public member indirectly calls the Invoke method on the supplied parameter. パブリック メンバーが必要なアクセス許可を確認しない場合、セキュリティ システムは呼び出し元が大きな権限を持っていると判断するため、その Invoke メソッド呼び出しは常に成功します。If the public member does not perform the necessary permission checks, the call to the Invoke method will always succeed, because the security system determines that the caller is highly trusted. 悪意のあるコードがそのメソッドを直接呼び出すアクセス許可を持っていなくても、パブリック メンバーを呼び出すことによって間接的にこのメソッドを呼び出すことができます。Even if malicious code does not have the permission to directly invoke the method, it can still do so indirectly by calling the public member.

バージョン情報Version Information

  • .NET Framework 4 以降では、透過的なコードからリフレクションを使用してセキュリティ クリティカルなメンバーにアクセスすることはできません。Beginning with the .NET Framework 4, transparent code cannot use reflection to access security-critical members.

  • ReflectionPermissionFlag.RestrictedMemberAccess フラグは、.NET Framework 2.0 Service Pack 1 で導入されています。The ReflectionPermissionFlag.RestrictedMemberAccess flag is introduced in the .NET Framework 2.0 Service Pack 1. 以前のバージョンの .NET Framework では、コードから非パブリック メンバーにアクセスするためにリフレクションを使用するには ReflectionPermissionFlag.MemberAccess フラグを指定する必要がありました。Earlier versions of the .NET Framework require the ReflectionPermissionFlag.MemberAccess flag for code that uses reflection to access nonpublic members. このアクセス許可は、部分的に信頼されるコードには絶対に付与しないでください。This is a permission that should never be granted to partially trusted code.

  • .NET Framework 2.0 以降、リフレクションを使用して非パブリックな型とメンバーに関する情報を取得する場合、アクセス許可が不要になりました。Beginning with the .NET Framework 2.0, using reflection to obtain information about nonpublic types and members does not require any permissions. 以前のバージョンでは、ReflectionPermissionReflectionPermissionFlag.TypeInformation フラグを指定する必要があります。In earlier versions, ReflectionPermission with the ReflectionPermissionFlag.TypeInformation flag is required.

関連項目See also