리플렉션의 보안 고려 사항

업데이트: 2007년 11월

리플렉션은 형식 및 멤버에 대한 정보를 가져오고 멤버에 액세스하는 기능을 제공합니다. public이 아닌 멤버에 액세스하면 보안 위험이 발생할 수 있습니다. 따라서 public이 아닌 멤버에 액세스하는 코드에는 해당 플래그가 지정된 ReflectionPermission이 필요합니다. 또한 증명 자료 제공, 비관리 코드 실행, 개체 serialize 등의 일부 작업에는 SecurityPermission이 필요합니다.

모든 코드에서는 리플렉션을 사용하여 권한 없이도 다음 작업을 수행할 수 있습니다.

  • 형식과 멤버를 열거하고 해당 메타데이터를 검사합니다.

  • 어셈블리 및 모듈을 열거하고 검사합니다.

  • public 멤버에 액세스합니다.

  • 호출 코드 기본 클래스의 protected 멤버에 액세스합니다. 리플렉션에서는 이를 패밀리 수준 액세스라고 합니다.

  • 호출 코드의 어셈블리에서 internal 멤버(Visual Basic의 경우 Friend 멤버)에 액세스합니다. 리플렉션에서는 이를 어셈블리 수준 액세스라고 합니다.

public이 아닌 멤버에 액세스

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

  • 코드에서 public이 아닌 멤버를 호출할 수 있게 하려면 ReflectionPermissionFlag.MemberAccess 플래그가 지정된 ReflectionPermission 권한을 부여해야 합니다.

    참고:

    기본적으로 보안 정책은 인터넷에서 발생한 코드에 대해 이 권한을 거부합니다. 인터넷에서 발생한 코드에는 이 권한을 부여하면 안 됩니다.

  • 호출된 멤버를 포함하는 어셈블리의 부여 집합이 호출 코드를 포함하는 어셈블리의 부여 집합과 같거나 그 하위 집합인 경우 코드에서 public이 아닌 멤버를 호출할 수 있게 하려면 ReflectionPermissionFlag.RestrictedMemberAccess 플래그가 지정된 ReflectionPermission 권한을 부여해야 합니다.

예를 들어 응용 프로그램 도메인에 인터넷 권한과 ReflectionPermissionFlag.RestrictedMemberAccess 플래그가 지정된 ReflectionPermission을 부여한 다음 두 개의 어셈블리 A와 B를 사용하여 인터넷 응용 프로그램을 실행한다고 가정합니다.

  • A에 부여되지 않은 권한이 어셈블리 B의 권한 집합에도 포함되어 있지 않으므로 어셈블리 A는 리플렉션을 사용하여 어셈블리 B의 private 멤버에 액세스할 수 있습니다.

  • 어셈블리 A가 리플렉션을 사용하여 .NET Framework 어셈블리의 private 멤버(예: mscorlib.dll)에 액세스할 수 없다면 mscorlib.dll이 완전히 신뢰되어 있고 어셈블리 A에 부여된 권한이 없기 때문입니다. 코드 액세스 보안이 런타임에 스택을 워크하면 MemberAccessException이 throw됩니다.

ReflectionPermissionFlag.RestrictedMemberAccess 플래그가 지정된 ReflectionPermission을 부여하는 샌드박스 응용 프로그램 도메인의 예제는 연습: 부분 신뢰 시나리오에서 코드 내보내기를 참조하십시오.

Serialization

serialization의 경우 SecurityPermissionAttribute.SerializationFormatter 플래그가 지정된 SecurityPermission은 액세스 가능성에 관계없이 serialize할 수 있는 형식의 멤버를 가져오고 설정하는 기능을 제공합니다. 이 권한이 있으면 코드에서 인스턴스의 전용 상태를 검색하고 변경할 수 있습니다. 적절한 권한이 부여되는 것 이외에도, 해당 형식이 메타데이터에서 serialize할 수 있는 것으로 표시되어 있어야 합니다.

링크 요청 검사

메서드나 대리자에 권한 P에 대한 LinkDemand가 있는 경우 런타임에서 메서드나 대리자의 호출자에 대해 링크 요청 검사를 수행하여 호출자에게 권한 P가 부여되었는지 확인합니다. 이 링크 요청 검사는 형식 정보를 검색할 때와 호출할 때 모두 수행됩니다.

MethodInfo 형식의 매개 변수 작성 안 함

특히 신뢰 수준이 높은 코드의 경우 MethodInfo 매개 변수를 사용하는 공용 API를 작성하지 마십시오. 이러한 API는 악성 코드에 더욱 노출되기 쉬울 수 있습니다. 예를 들어 MethodInfo 매개 변수를 사용하는 신뢰 수준이 높은 코드의 공용 API를 고려해 보십시오. 공용 API가 제공된 매개 변수에 대해 간접적으로 Invoke 메서드를 호출한다고 가정합니다. 공용 API가 필요한 권한 검사를 수행하지 않으면 보안 시스템에서는 호출자의 신뢰 수준이 높다고 결정하기 때문에 Invoke 메서드에 대한 호출이 항상 성공적으로 수행됩니다. 악성 코드는 이 메서드를 직접 호출하는 권한이 없어도 공용 API를 호출하여 간접적으로 이 메서드를 호출할 수 있습니다.

버전 정보

.NET Framework 버전 2.0 서비스 팩 1에서는 ReflectionPermissionFlag.RestrictedMemberAccess 플래그가 도입되었습니다. .NET Framework 이전 버전에서 리플렉션을 사용하여 public이 아닌 멤버에 액세스하는 코드의 경우 ReflectionPermissionFlag.MemberAccess 플래그가 필요합니다. 이렇게 부분적으로 신뢰할 수 있는 코드에는 이 권한을 부여하면 안 됩니다.

참고:

ReflectionPermissionFlag.RestrictedMemberAccess 플래그를 사용하려면 응용 프로그램이 .NET Framework 버전 3.5를 대상으로 해야 합니다. 자세한 내용은 .NET Framework 3.5 아키텍처를 참조하십시오.

.NET Framework 2.0부터 시작하여 리플렉션을 통해 public이 아닌 형식과 멤버에 대한 정보를 가져오는 데 권한이 필요하지 않습니다. 이전 버전에는 ReflectionPermissionFlag.TypeInformation 플래그가 지정된 ReflectionPermission이 필요합니다.

참고 항목

개념

리플렉션 내보내기의 보안 문제점

형식 정보 보기

특성 적용

사용자 지정 특성 액세스

참조

ReflectionPermissionFlag

ReflectionPermission

SecurityPermission