Share via


CA2118: SuppressUnmanagedCodeSecurityAttribute 사용을 검토하십시오.

항목
RuleId CA2118
범주 Microsoft.Security
주요 변경 내용 주요 변경

원인

public 또는 protected 형식이나 멤버에 System.Security.SuppressUnmanagedCodeSecurityAttribute 특성이 있습니다.

참고 항목

이 규칙은 더 이상 사용되지 않습니다. 자세한 내용은 사용되지 않는 규칙을 참조하세요.

규칙 설명

SuppressUnmanagedCodeSecurityAttribute는 COM interop 또는 플랫폼 호출을 사용하여 비관리 코드를 실행하는 멤버에 대한 기본 보안 시스템 동작을 변경합니다. 일반적으로 시스템은 비관리 코드 권한을 위한 데이터 및 모델링을 수행합니다. 이 요청은 런타임에 멤버를 호출할 때마다 발생하며, 호출 스택에 있는 모든 호출자의 권한을 검사합니다. 해당 특성이 있으면 시스템은 권한을 위한 링크 요청을 수행합니다. 호출자가 JIT 컴파일될 때 직접 실행 호출자의 권한을 검사합니다.

이 특성은 기본적으로 성능 향상을 위해 사용되지만 성능이 향상되는 대신 중대한 보안 위험이 발생합니다. 네이티브 메서드를 호출하는 public 멤버에 특성을 배치하는 경우 직접 실행 호출자가 아닌 호출 스택의 다른 호출자는 비관리 코드 권한이 없어도 비관리 코드를 실행할 수 있습니다. public 멤버의 작업과 입력 처리에 따라 특성을 통해 신뢰할 수 없는 호출자가 정상적으로 신뢰할 수 있는 코드로 제한되는 기능에 액세스할 수 있게 됩니다.

.NET은 보안 검사를 사용하여 호출자가 현재 프로세스의 주소 공간에 직접 액세스할 수 없도록 방지합니다. 이 특성은 정상적인 보안을 무시하므로 코드가 프로세스의 메모리를 읽거나 쓰는 데 사용될 수 있는 경우 심각한 위협이 됩니다. 위험이 의도적으로 프로세스 메모리에 대한 액세스를 제공하는 메서드로 제한되는 것은 아닙니다. 악성 코드가 놀랍거나 잘못된 형식이거나 유효하지 않은 입력을 제공하는 등 어떤 수단으로든 액세스에 성공할 수 있는 모든 시나리오에도 위험이 있습니다.

기본 보안 정책은 로컬 컴퓨터에서 실행되거나 다음 그룹 중 하나의 멤버가 아닌 한 어셈블리에 비관리 코드 권한을 부여하지 않습니다.

  • 내 컴퓨터 영역 코드 그룹

  • Microsoft 강력한 이름 코드 그룹

  • ECMA 강력한 이름 코드 그룹

위반 문제를 해결하는 방법

코드를 신중하게 검토하여 이 특성이 반드시 필요한지 확인합니다. 관리 코드 보안에 익숙하지 않거나 이 특성을 사용하는 경우 보안에 미치는 영향을 모르겠으면 코드에서 특성을 제거합니다. 특성이 필요한 경우 호출자가 코드를 악의적으로 사용할 수 없도록 해야 합니다. 코드에 비관리 코드를 실행할 수 있는 권한이 없는 경우 이 특성은 아무 영향도 주지 않으므로 제거해야 합니다.

경고를 표시하지 않는 경우

이 규칙의 경고를 안전하게 표시하지 않으려면 코드에서 안전하지 않은 방식으로 사용될 수 있는 네이티브 작업이나 리소스에 대한 액세스를 호출자에게 제공하지 않도록 해야 합니다.

예 1

다음 예제에서는 규칙을 위반합니다.

using System.Security;

// These two classes are identical
// except for the location of the attribute.

namespace SecurityRulesLibrary
{
    public class MyBadMemberClass
   {
      [SuppressUnmanagedCodeSecurityAttribute()]
      public void DoWork()
      {
         FormatHardDisk();
      }

      void FormatHardDisk()
      {
         // Code that calls unmanaged code.
      }
   }

   [SuppressUnmanagedCodeSecurityAttribute()]
   public class MyBadTypeClass
   {
      public void DoWork()
      {
         FormatHardDisk();
      }

      void FormatHardDisk()
      {
         // Code that calls unmanaged code.
      }
   }
}

예제 2

다음 예제에서 DoWork 메서드는 플랫폼 호출 메서드 FormatHardDisk에 공개적으로 액세스할 수 있는 코드 경로를 제공합니다.

using System.Security;
using System.Runtime.InteropServices;

namespace SecurityRulesLibrary
{
   public class SuppressIsOnPlatformInvoke
   {
      // The DoWork method is public and provides unsecured access
      // to the platform invoke method FormatHardDisk.
      [SuppressUnmanagedCodeSecurityAttribute()]
      [DllImport("native.dll")]

      private static extern void FormatHardDisk();
      public void DoWork()
      {
         FormatHardDisk();
      }
   }

   // Having the attribute on the type also violates the rule.
   [SuppressUnmanagedCodeSecurityAttribute()]
   public class SuppressIsOnType
   {
      [DllImport("native.dll")]

      private static extern void FormatHardDisk();
      public void DoWork()
      {
         FormatHardDisk();
      }
   }
}

예 3

다음 예제의 public 메서드 DoDangerousThing에서 위반이 발생합니다. 위반 문제를 해결하려면 DoDangerousThing을 private으로 설정해야 하며, DoWork 메서드에 설명된 대로 보안 요청으로 보호된 public 메서드를 통해 액세스해야 합니다.

using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;

namespace SecurityRulesLibrary
{
   [SuppressUnmanagedCodeSecurityAttribute()]
   public class BadTypeWithPublicPInvokeAndSuppress
   {
      [DllImport("native.dll")]

      public static extern void DoDangerousThing();
      public void DoWork()
      {
         // Note that because DoDangerousThing is public, this 
         // security check does not resolve the violation.
         // This only checks callers that go through DoWork().
         SecurityPermission secPerm = new SecurityPermission(
            SecurityPermissionFlag.ControlPolicy | 
            SecurityPermissionFlag.ControlEvidence
         );
         secPerm.Demand();
         DoDangerousThing();
      }
   }
}

참고 항목