리플렉션의 보안 고려 사항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. 또한 신뢰할 수 있는 코드만 리플렉션을 사용하여 컴파일된 코드에서 직접 액세스할 수 없는 public이 아닌 멤버에 액세스할 수 있습니다.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:

  • 보안에 중요하지 않은 public 멤버에 액세스합니다.Access public members that are not security-critical.

  • 해당 멤버가 보안에 중요하지 않은 경우 컴파일된 코드에서 액세스할 수 있는 public이 아닌 멤버에 액세스합니다.Access nonpublic members that would be accessible to compiled code, if those members are not security-critical. public이 아닌 이러한 멤버의 예는 다음과 같습니다.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 멤버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:

이러한 규칙은 보안에 중요한 멤버를 컴파일된 코드에서 직접 액세스하는지 또는 리플렉션을 사용하여 액세스하는지에 관계없이 동일합니다.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의 보안 모델에 대한 자세한 내용은 보안 변경 내용을 참조하세요.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. 리플렉션은 형식의 투명도 수준을 검색할 수 있게 해주는 IsSecurityCritical, IsSecuritySafeCriticalIsSecurityTransparent 속성을 제공합니다.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.

MethodBase, FieldInfo, TypeBuilder, MethodBuilderDynamicMethod 클래스에도 비슷한 속성이 있습니다.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

리플렉션을 사용하여 공용 언어 런타임의 접근성 규칙에 따라 액세스할 수 없는 멤버를 호출하려면 코드에 다음 두 가지 권한 중 하나를 부여해야 합니다.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:

  • 코드에서 public이 아닌 멤버를 호출할 수 있게 하려면 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.

  • 호출된 멤버를 포함하는 어셈블리의 권한 부여 집합이 호출 코드를 포함하는 어셈블리의 권한 부여 집합과 같거나 하위 집합인 경우 코드가 public이 아닌 멤버를 호출할 수 있도록 허용하려면 다음을 수행합니다. 코드는 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.RestrictedMemberAccess 플래그를 통한 ReflectionPermission을 부여한 다음 두 어셈블리 A와 B를 사용하여 인터넷 애플리케이션을 실행한다고 가정합니다.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의 private 멤버에 액세스할 수 있습니다.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.

  • mscorlib.dll은 완전히 신뢰할 수 있어 어셈블리 A에 부여되지 않은 권한이 있으므로 어셈블리 A가 리플렉션을 사용하여 mscorlib.dll과 같은 .NET Framework 어셈블리의 private 멤버에 액세스할 수 없습니다. 런타임에 코드 액세스 보안이 스택을 이동하는 경우 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.

SerializationSerialization

직렬화를 위해 SecurityPermissionAttribute.SerializationFormatter 플래그가 있는 SecurityPermission은 접근성에 관계없이 직렬화 가능 형식의 멤버를 가져오고 설정하는 기능을 제공합니다.For serialization, SecurityPermission with the SecurityPermissionAttribute.SerializationFormatter flag provides the ability to get and set members of serializable types, regardless of accessibility. 이 권한을 통해 코드에서 인스턴스의 private 상태를 검색하고 변경할 수 있습니다.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 매개 변수를 사용하는 public 멤버를 작성하지 마세요.Avoid writing public members that take MethodInfo parameters, especially for trusted code. 이러한 멤버는 악성 코드에 더 취약할 수 있습니다.Such members might be more vulnerable to malicious code. 예를 들어 MethodInfo 매개 변수를 사용하는 신뢰할 수 있는 코드의 public 멤버를 살펴보겠습니다.For example, consider a public member in highly trusted code that takes a MethodInfo parameter. public 멤버가 제공된 매개 변수에 대해 Invoke 메서드를 간접적으로 호출한다고 가정합니다.Assume that the public member indirectly calls the Invoke method on the supplied parameter. public 멤버가 필요한 권한 검사를 수행하지 않는 경우 보안 시스템에서 호출자를 신뢰할 수 있는 것으로 결정하기 때문에 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. 악성 코드에 메서드를 직접 호출할 수 있는 권한이 없는 경우에도 public 멤버를 호출하여 간접적으로 호출할 수 있습니다.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 서비스 팩 1에 도입되었습니다.The ReflectionPermissionFlag.RestrictedMemberAccess flag is introduced in the .NET Framework 2.0 Service Pack 1. 이전 버전의 .NET Framework에서는 리플렉션을 사용하여 public이 아닌 멤버에 액세스하는 코드에 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부터 리플렉션을 사용하여 public이 아닌 형식과 멤버에 대한 정보를 가져오는 데 필요한 권한은 없습니다.Beginning with the .NET Framework 2.0, using reflection to obtain information about nonpublic types and members does not require any permissions. 이전 버전에서는 ReflectionPermissionFlag.TypeInformation 플래그가 있는 ReflectionPermission이 필요합니다.In earlier versions, ReflectionPermission with the ReflectionPermissionFlag.TypeInformation flag is required.

참고 항목See also