|Important||This document may not represent best practices for current development, links to downloads and other resources may no longer be valid. Current recommended version can be found here.|
Security Considerations for Reflection
Reflection provides the ability to obtain information about types and members, and to access members. Accessing nonpublic members could create a security risk. Therefore, code that accesses nonpublic members requires ReflectionPermission with the appropriate flags. In addition, SecurityPermission is required for some tasks, such as supplying evidence, executing unmanaged code, and serializing objects.
All code can use reflection to perform the following tasks without permissions:
Enumerate types and members, and examine their metadata.
Enumerate and examine assemblies and modules.
Access public members.
Access protected members of the calling code's base classes. (In reflection, this is referred to as family-level access.)
Access internal members (Friend members in Visual Basic) in the calling code's assembly. (In reflection, this is referred to as assembly-level access.)
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:
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.
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: ReflectionPermission with the ReflectionPermissionFlag.RestrictedMemberAccess flag.
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.
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.
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.
For an example of a sandboxed application domain that grants ReflectionPermission with the ReflectionPermissionFlag.RestrictedMemberAccess flag, see Walkthrough: Emitting Code in Partial Trust Scenarios.
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.)
If a method or a delegate has a LinkDemand for permission P, the runtime will perform a link demand check against the caller of the method or delegate to verify that the caller has been granted permission P. This link demand check occurs both for discovery of type information and for invocation.
Avoid writing public APIs that take MethodInfo parameters, especially for highly trusted code. Such APIs might be more vulnerable to malicious code. For example, consider a public API in highly trusted code that takes a MethodInfo parameter. Assume that the public API indirectly calls the Invoke method on the supplied parameter. If the public API 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 API.
The ReflectionPermissionFlag.RestrictedMemberAccess flag is introduced in the .NET Framework version 2.0 Service Pack 1. 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.
Beginning with the .NET Framework 2.0, using reflection to obtain information about nonpublic types and members does not require any permissions. In earlier versions, ReflectionPermission with the ReflectionPermissionFlag.TypeInformation flag is required.