Share via


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

.NET Framework는 MSIL(Microsoft Intermediate Language)을 내보내는 세 가지 방법을 제공합니다. 각 방법에는 고유한 보안 문제가 있습니다.

  • 동적 어셈블리

  • 익명으로 호스팅된 동적 메서드

  • 기존 어셈블리와 관련된 동적 메서드

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

참고참고

코드에 반영하고 코드를 생성하는 데 필요한 권한이 .NET Framework의 이후 릴리스에서는 변경되었습니다.이 항목의 뒷부분에 나오는 버전 정보를 참조하십시오.

동적 어셈블리

동적 어셈블리는 AppDomain.DefineDynamicAssembly 메서드의 오버로드를 사용하여 만들어집니다. .NET Framework 버전 4에서는 컴퓨터 전체 보안 정책이 사용되지 않으므로 이 메서드의 오버로드 대부분이 더 이상 사용되지 않습니다. .NET Framework 4의 보안 변경 내용을 참조하십시오. 나머지 오버로드는 신뢰 수준에 상관없이 임의의 코드에서 실행할 수 있습니다. 이러한 오버로드는 크게 두 그룹으로 분류됩니다. 한 그룹의 오버로드는 작성 시 동적 어셈블리에 적용할 특성의 목록을 지정하고, 다른 그룹의 오버로드는 이를 지정하지 않습니다. 작성 시 SecurityRulesAttribute 특성을 적용하여 어셈블리에 대한 투명성 모델을 지정하지 않으면 내보내는 어셈블리에서 투명성 모델이 상속됩니다.

참고참고

작성 후 SetCustomAttribute 메서드를 사용하여 동적 어셈블리에 적용하는 특성은 어셈블리를 디스크에 저장하고 다시 메모리로 로드하기 전까지 어셈블리에 영향을 주지 않습니다.

동적 어셈블리의 코드는 다른 어셈블리의 노출 형식과 멤버에 액세스할 수 있습니다.

참고참고

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

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

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

인터넷 권한이 있는 어셈블리에서 임시 동적 어셈블리를 생성하고 해당 코드를 실행할 수 있는 다음 조건을 확인해 보십시오.

  • 동적 어셈블리에서 다른 어셈블리의 public 형식과 멤버만 사용합니다.

  • 이러한 형식과 멤버에 필요한 권한이 부분적으로 신뢰할 수 있는 어셈블리의 부여 집합에 들어 있습니다.

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

  • 디버그 기호가 생성되지 않습니다. Internet 및 LocalIntranet 권한 집합에는 필수 권한이 포함되지 않습니다.

익명으로 호스팅된 동적 메서드

연결된 형식이나 모듈을 지정하지 않는 두 개의 DynamicMethod 생성자(DynamicMethod(String, Type, Type[]) 및 DynamicMethod(String, Type, Type[], Boolean))를 사용하여 익명으로 호스팅된 동적 메서드를 만듭니다. 이 생성자는 시스템에서 제공된 완전히 신뢰할 수 있는 보안 투명 어셈블리에 동적 메서드를 넣습니다. 이러한 생성자를 사용하거나 동적 메서드에 대한 코드를 생성하는 경우에는 권한이 필요하지 않습니다.

대신 익명으로 호스팅된 동적 메서드를 만들 때 호출 스택이 캡처됩니다. 메서드를 생성하면 캡처된 호출 스택에 대해 보안 요청이 수행됩니다.

참고참고

개념적으로 메서드를 생성하는 동안 요청이 수행됩니다.즉, 각 MSIL 명령을 내보낼 때 요청을 수행할 수 있습니다.현재 구현에서는 DynamicMethod.CreateDelegate 메서드를 호출할 때 또는 CreateDelegate를 호출하지 않고 메서드를 호출하는 경우 JIT(Just-In-Time) 컴파일러를 호출할 때 모든 요청이 수행됩니다.

응용 프로그램 도메인에서 허용하는 경우, 익명으로 호스팅된 동적 메서드는 JIT 가시성 검사를 건너뛸 수 있지만 다음 제한이 적용됩니다. 익명으로 호스팅된 동적 메서드에서 액세스하는 public이 아닌 형식과 멤버는 부여 집합이 내보내는 호출 스택의 부여 집합과 같거나 그 하위 집합인 어셈블리에 있어야 합니다. JIT 가시성 검사를 건너뛰는 이 제한된 기능은 응용 프로그램 도메인에서 ReflectionPermissionFlag.RestrictedMemberAccess 플래그가 지정된 ReflectionPermission을 부여한 경우에 사용할 수 있습니다.

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

  • JIT 가시성 검사를 건너뛰도록 지정하면 메서드를 생성할 때 수행되는 요청에 ReflectionPermissionFlag.RestrictedMemberAccess 플래그가 지정된 ReflectionPermission 및 액세스되는 public이 아닌 멤버가 있는 어셈블리의 부여 집합이 포함됩니다.

public이 아닌 멤버의 부여 집합을 고려하기 때문에 ReflectionPermissionFlag.RestrictedMemberAccess가 부여된 부분적으로 신뢰할 수 있는 코드는 신뢰할 수 있는 어셈블리의 public이 아닌 멤버를 실행하여 권한을 올릴 수 없습니다.

다른 생성된 코드와 마찬가지로 동적 메서드를 실행하려면 동적 메서드에서 사용하는 메서드에 필요한 모든 권한이 있어야 합니다.

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

자세한 내용은 DynamicMethod 클래스를 참조하십시오.

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

인터넷 권한이 있는 어셈블리에서 익명으로 호스팅된 동적 메서드를 생성하고 실행할 수 있는 다음 조건을 확인해 보십시오.

  • 동적 메서드에서 public 형식과 멤버만 사용합니다. 부여 집합에 ReflectionPermissionFlag.RestrictedMemberAccess가 있으면 해당 부여 집합이 내보내는 어셈블리의 부여 집합과 같거나 그 하위 집합인 모든 어셈블리의 public이 아닌 형식과 멤버를 사용할 수 있습니다.

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

참고참고

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

기존 어셈블리와 관련된 동적 메서드

동적 메서드를 기존 어셈블리의 형식이나 모듈과 연결하려면 관련된 형식 또는 모듈을 지정하는 DynamicMethod 생성자를 사용합니다. 동적 메서드를 기존 형식 또는 모듈과 연결하면 public이 아닌 형식과 멤버에 대한 액세스 권한이 동적 메서드에 제공되므로 이 생성자를 호출하는 데 필요한 권한은 달라질 수 있습니다.

  • 특정 형식과 관련된 동적 메서드는 해당 형식의 모든 멤버(private 멤버 포함) 및 관련된 형식을 포함하는 어셈블리의 모든 내부 형식과 멤버에 액세스할 수 있습니다.

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

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

생성자에 필요한 권한은 동적 메서드에 제공하려는 액세스 권한에 따라 달라집니다.

이 목록의 항목은 내보내는 어셈블리의 부여 집합과 관련해서 설명되어 있지만 요청은 응용 프로그램 도메인 경계를 비롯한 전체 호출 스택에 대해 수행됩니다.

자세한 내용은 DynamicMethod 클래스를 참조하십시오.

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

참고참고

부분적으로 신뢰할 수 있는 코드에서 동적 메서드를 생성하려는 경우 익명으로 호스팅된 동적 메서드를 사용하는 것이 좋습니다.

인터넷 권한이 있는 어셈블리에서 동적 메서드를 생성하고 실행할 수 있는 다음 조건을 확인해 보십시오.

  • 동적 메서드가 해당 메서드를 내보내는 모듈 또는 형식과 관련이 있거나 부여 집합에 ReflectionPermissionFlag.RestrictedMemberAccess가 있고 해당 부여 집합이 내보내는 어셈블리의 부여 집합과 같거나 그 하위 집합인 어셈블리의 모듈과 관련이 있습니다.

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

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

  • 동적 메서드에서 JIT 가시성 검사를 건너뛰지 않습니다.

참고참고

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

버전 정보

.NET Framework 4부터는 시스템 전체 보안 정책이 사용되지 않으며 보안 투명성이 기본 적용 메커니즘으로 사용됩니다. .NET Framework 4의 보안 변경 내용를 참조하십시오.

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

참고참고

ReflectionPermissionFlag.ReflectionEmit 플래그가 지정된 ReflectionPermission은 기본적으로 FullTrust 및 LocalIntranet 명명된 권한 집합에 있지만 Internet 권한 집합에는 포함되지 않습니다.따라서 .NET Framework의 이전 버전에서는 라이브러리가 ReflectionEmit에 대해 Assert를 실행하는 경우에만 인터넷 권한으로 라이브러리를 사용할 수 있습니다.코드 오류가 있으면 보안에 문제가 생길 수 있으므로 이러한 라이브러리를 보안 측면에서 자세히 검토해야 합니다..NET Framework 2.0 SP1의 경우에는 기본적으로 코드를 생성하는 데 권한이 필요하지 않으므로 부분 신뢰 시나리오에서 보안 요구 사항 없이 코드를 생성할 수 있습니다.즉, 생성된 코드에는 이를 내보내는 어셈블리보다 많은 권한이 부여되지 않습니다.따라서 코드를 생성하는 라이브러리의 보안이 투명하게 유지되고 ReflectionEmit을 어설션할 필요가 없으므로 보안 라이브러리를 간편하게 작성할 수 있습니다.

또한 .NET Framework 2.0 SP1에서는 부분적으로 신뢰할 수 있는 동적 메서드에서 public이 아닌 형식과 멤버에 액세스하기 위한 ReflectionPermissionFlag.RestrictedMemberAccess 플래그가 도입되었습니다. .NET Framework의 이전 버전에서는 public이 아닌 형식과 멤버에 액세스하는 동적 메서드에 대해 ReflectionPermissionFlag.MemberAccess 플래그가 필요한데, 이는 부분적으로 신뢰할 수 있는 코드에 부여하면 안 되는 권한입니다.

마지막으로 .NET Framework 2.0 SP1에서는 익명으로 호스팅된 메서드가 도입되었습니다.

형식 및 멤버에 대한 정보 가져오기

.NET Framework 2.0부터 시작하여 public이 아닌 형식과 멤버에 대한 정보를 가져오는 데 권한이 필요하지 않습니다. 리플렉션을 통해 동적 메서드를 내보내는 데 필요한 정보를 가져옵니다. 예를 들어, MethodInfo 개체를 사용하여 메서드 호출을 내보냅니다. .NET Framework의 이전 버전에는 ReflectionPermissionFlag.TypeInformation 플래그가 지정된 ReflectionPermission이 필요합니다. 자세한 내용은 리플렉션의 보안 고려 사항을 참조하십시오.

참고 항목

개념

리플렉션의 보안 고려 사항

기타 리소스

동적 메서드 및 어셈블리 생성