다음을 통해 공유


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

.NET Framework는 각각 고유한 보안 문제가 있는 CIL(공용 중간 언어)을 내보내는 세 가지 방법을 제공합니다.

동적 코드를 생성하는 방법에 관계없이 생성된 코드를 실행하려면 생성된 코드에서 사용하는 형식 및 메서드에 필요한 모든 권한이 필요합니다.

비고

.NET Framework의 후속 릴리스에 따라 코드 반영과 코드 방출에 필요한 권한이 변경되었습니다. 이 문서의 뒷부분에 있는 버전 정보를 참조하세요.

동적 어셈블리

동적 어셈블리는 메서드의 AppDomain.DefineDynamicAssembly 오버로드를 사용하여 생성됩니다. 이 메서드의 대부분의 오버로드는 컴퓨터 전체 보안 정책이 제거되어 .NET Framework 4에서 더 이상 사용되지 않습니다. 나머지 오버로드는 신뢰 수준에 관계없이 모든 코드에서 실행할 수 있습니다. 이러한 오버로드는 동적 어셈블리를 만들 때 적용할 특성 목록을 지정하는 그룹과 그렇지 않은 두 그룹으로 나분합니다. 어셈블리를 만들 때 SecurityRulesAttribute 특성을 적용하지 않으면, 투명도 모델이 어셈블리를 내보내는 쪽에서 상속됩니다.

비고

동적 어셈블리를 만든 후 적용하는 특성은 메서드를 SetCustomAttribute 사용하여 어셈블리가 디스크에 저장되고 메모리에 다시 로드될 때까지 적용되지 않습니다.

동적 어셈블리의 코드는 다른 어셈블리의 표시되는 형식 및 멤버에 액세스할 수 있습니다.

비고

동적 어셈블리는 동적 메서드가 비공개 형식 및 멤버에 액세스할 수 있도록 허용하는 ReflectionPermissionFlag.MemberAccessReflectionPermissionFlag.RestrictedMemberAccess 플래그를 사용하지 않습니다.

임시 동적 어셈블리는 메모리에 만들어지고 디스크에 저장되지 않으므로 파일 액세스 권한이 필요하지 않습니다. 디스크에 동적 어셈블리를 저장하려면 적절한 플래그가 필요합니다 FileIOPermission .

부분적으로 신뢰할 수 있는 코드에서 동적 어셈블리 생성

인터넷 권한이 있는 어셈블리가 임시 동적 어셈블리를 생성하고 해당 코드를 실행할 수 있는 조건을 고려합니다.

  • 동적 어셈블리는 공용 형식 및 다른 어셈블리의 멤버만 사용합니다.

  • 이러한 형식 및 멤버가 요구하는 권한은 부분적으로 신뢰할 수 있는 어셈블리의 권한 부여 집합에 포함됩니다.

  • 어셈블리가 디스크에 저장되지 않습니다.

  • 디버그 기호는 생성되지 않습니다. (InternetLocalIntranet 사용 권한 집합에는 필요한 권한이 포함되지 않습니다.)

익명으로 호스트되는 동적 메서드

익명으로 호스트되는 동적 메서드는 연결된 형식 또는 모듈 DynamicMethod 을 지정하지 않는 두 DynamicMethod(String, Type, Type[]) 생성자를 사용하여 만들어집니다DynamicMethod(String, Type, Type[], Boolean). 이러한 생성자는 동적 메서드를 시스템에서 제공하는 완전히 신뢰할 수 있는 보안 투명 어셈블리에 배치합니다. 이러한 생성자를 사용하거나 동적 메서드에 대한 코드를 내보내는 데 필요한 권한은 없습니다.

대신 익명으로 호스트되는 동적 메서드가 만들어지면 호출 스택이 캡처됩니다. 메서드가 생성되면 캡처된 호출 스택에 대한 보안 요구가 발생합니다.

비고

개념적으로 메서드를 생성할 때 요구가 발생합니다. 즉, 각 CIL 명령이 내보내질 때 요청이 발생할 수 있습니다. 현재 구현에서는 DynamicMethod.CreateDelegate 메서드를 호출하거나 CreateDelegate 메서드를 호출하지 않은 경우 JIT(Just-In-Time) 컴파일러가 호출될 때 모든 요구가 발생합니다.

애플리케이션 도메인에서 허용하는 경우 익명으로 호스트된 동적 메서드는 JIT 표시 유형 검사를 건너뛸 수 있으며, 다음 제한 사항이 적용됩니다. 익명으로 호스트된 동적 메서드에서 액세스하는 비공개 형식 및 멤버는 부여 집합이 내보내는 호출 스택의 권한 부여 집합과 같거나 하위 집합인 어셈블리에 있어야 합니다. 애플리케이션 도메인이 ReflectionPermissionReflectionPermissionFlag.RestrictedMemberAccess 플래그와 함께 부여하는 경우 JIT 가시성 검사를 건너뛰는 이 제한된 기능이 활성화됩니다.

  • 메서드가 공용 형식 및 멤버만 사용하는 경우 생성 중에 권한이 필요하지 않습니다.

  • JIT 가시성 검사를 건너뛰도록 지정한 경우, 메서드가 생성될 때 수행되는 요구 사항에는 액세스된 비공개 멤버가 포함된 어셈블리의 권한 부여 집합과 ReflectionPermission 플래그 및 ReflectionPermissionFlag.RestrictedMemberAccess가 포함됩니다.

게시되지 않은 멤버의 권한 부여 집합을 고려하므로 부여 ReflectionPermissionFlag.RestrictedMemberAccess 된 부분적으로 신뢰할 수 있는 코드는 신뢰할 수 있는 어셈블리의 게시되지 않은 멤버를 실행하여 권한을 상승시킬 수 없습니다.

다른 내보낸 코드와 마찬가지로 동적 메서드를 실행하려면 동적 메서드가 사용하는 메서드에서 요구하는 모든 권한이 필요합니다.

익명으로 호스팅되는 동적 메서드를 호스트하는 시스템 어셈블리는 .NET Framework 4 이전의 .NET Framework에서 사용된 투명도 모델인 투명도 모델을 사용합니다 SecurityRuleSet.Level1 .

자세한 내용은 DynamicMethod 클래스를 참조하세요.

부분적으로 신뢰할 수 있는 코드에서 익명으로 호스트된 동적 메서드 생성

인터넷 권한이 있는 어셈블리가 익명으로 호스트된 동적 메서드를 생성하고 실행할 수 있는 조건을 고려합니다.

  • 동적 메서드는 public 형식 및 멤버만 사용합니다. ReflectionPermissionFlag.RestrictedMemberAccess가 권한 부여 집합에 포함되는 경우, 내보내는 어셈블리의 권한 부여 집합과 같거나 하위 집합인 어셈블리의 비공개 형식 및 멤버를 사용할 수 있습니다.

  • 동적 메서드에서 사용하는 모든 형식 및 멤버에 필요한 사용 권한은 부분적으로 신뢰할 수 있는 어셈블리의 권한 부여 집합에 포함됩니다.

비고

동적 메서드는 디버그 기호를 지원하지 않습니다.

기존 어셈블리와 연결된 동적 메서드

동적 메서드를 기존 어셈블리의 DynamicMethod 형식 또는 모듈과 연결하려면 연결된 형식 또는 모듈을 지정하는 생성자를 사용합니다. 동적 메서드를 기존 형식 또는 모듈과 연결하면 동적 메서드가 게시되지 않은 형식 및 멤버에 액세스할 수 있으므로 이러한 생성자를 호출하는 데 필요한 권한은 다양합니다.

  • 형식과 연결된 동적 메서드는 해당 형식의 모든 멤버, 심지어 프라이빗 멤버, 연결된 형식을 포함하는 어셈블리의 모든 내부 형식 및 멤버에 액세스할 수 있습니다.

  • 모듈과 연결된 동적 메서드는 모듈의 internal 모든 형식 및 멤버(Friend Visual Basic, assembly 공용 언어 런타임 메타데이터)에 액세스할 수 있습니다.

또한 JIT 컴파일러의 표시 유형 검사를 건너뛰는 기능을 지정하는 생성자를 사용할 수 있습니다. 이렇게 하면 액세스 수준에 관계없이 모든 어셈블리의 모든 형식 및 멤버에 대한 동적 메서드 액세스 권한이 부여됩니다.

생성자가 요구하는 권한은 동적 메서드를 제공하기로 결정한 액세스의 양에 따라 달라집니다.

이 목록의 항목은 내보내는 어셈블리의 권한 부여 집합에 대해 설명되지만 애플리케이션 도메인 경계를 포함하여 전체 호출 스택에 대한 요구가 수행된다는 점을 기억하세요.

자세한 내용은 DynamicMethod 클래스를 참조하세요.

부분적으로 신뢰할 수 있는 코드에서 동적 메서드 생성

비고

부분적으로 신뢰할 수 있는 코드에서 동적 메서드를 생성하는 권장 방법은 익명으로 호스트된 동적 메서드를 사용하는 것입니다.

인터넷 권한이 있는 어셈블리가 동적 메서드를 생성하고 실행할 수 있는 조건을 고려합니다.

  • 동적 메서드는 모듈을 내보내는 모듈 또는 형식과 연결되거나 해당 권한 부여 집합이 포함 ReflectionPermissionFlag.RestrictedMemberAccess 되며, 권한 부여 집합이 내보내는 어셈블리의 권한 부여 집합과 같거나 하위 집합인 어셈블리의 모듈과 연결됩니다.

  • 동적 메서드는 public 형식 및 멤버만 사용합니다. 해당 권한 부여 집합에 ReflectionPermissionFlag.RestrictedMemberAccess이(가) 포함되고, 해당 모듈이 내보내는 어셈블리의 권한 부여 집합과 같거나 하위 집합인 어셈블리의 모듈과 연결되어 있는 경우에는, 관련 모듈에서 internal (Friend은 Visual Basic에서, assembly은 공용 언어 런타임 메타데이터에서)을(를) 표시한 형식 및 멤버를 사용할 수 있습니다.

  • 동적 메서드에서 사용하는 모든 형식 및 멤버가 요구하는 권한은 부분적으로 신뢰할 수 있는 어셈블리의 권한 부여 집합에 포함됩니다.

  • 동적 메서드는 JIT 표시 유형 검사를 건너뛰지 않습니다.

비고

동적 메서드는 디버그 기호를 지원하지 않습니다.

버전 정보

.NET Framework 4부터는 머신 전체 보안 정책이 제거되고 보안 투명성이 기본 적용 메커니즘이 됩니다.

.NET Framework 2.0 서비스 팩 1부터는 ReflectionPermissionReflectionPermissionFlag.ReflectionEmit 플래그가 동적 어셈블리와 동적 메서드 내보낼 때 더 이상 필요하지 않습니다. 이 플래그는 모든 이전 버전의 .NET Framework에서 필요합니다.

비고

ReflectionPermission 플래그는 기본적으로 ReflectionPermissionFlag.ReflectionEmitFullTrust이라는 명명된 사용 권한 집합에 포함되지만 LocalIntranet 사용 권한 집합에는 포함되지 않습니다. 따라서 .NET Framework의 이전 버전에서는 라이브러리가 AssertReflectionEmit을(를) 실행하는 경우에만 인터넷 권한을 가지고 사용할 수 있습니다. 코딩 오류로 인해 보안 허점이 발생할 수 있으므로 이러한 라이브러리에는 신중한 보안 검토가 필요합니다. .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와 함께 필요합니다. 자세한 내용은 리플렉션에 대한 보안 고려 사항을 참조하세요.

참고하십시오