Share via


CA2118: Revisar el uso de SuppressUnmanagedCodeSecurityAttribute

Elemento Valor
RuleId CA2118
Category Microsoft.Security
Cambio importante Problemático

Causa

Un tipo o miembro público o protegido tiene el atributo System.Security.SuppressUnmanagedCodeSecurityAttribute.

Nota

Esta regla está en desuso. Para más información, consulte Reglas en desuso.

Descripción de la regla

SuppressUnmanagedCodeSecurityAttribute cambia el comportamiento del sistema de seguridad predeterminado por miembros que ejecutan código no administrado que utiliza la interoperabilidad COM o la invocación de plataforma. Por lo general, el sistema realiza el proceso indicado en Datos y modelado para el permiso de código no administrado. Esta demanda se produce en tiempo de ejecución para cada invocación del miembro y comprueba si el autor de la llamada de la pila de llamadas tiene permiso. Cuando el atributo está presente, el sistema realiza una solicitud de vínculo para el permiso: los permisos del llamador inmediato se comprueban cuando el autor de la llamada está compilado JIT.

Este atributo se utiliza principalmente para aumentar el rendimiento; sin embargo, las mejoras de rendimiento suponen riesgos de seguridad importantes. Si coloca el atributo en miembros públicos que llaman a métodos nativos, los llamadores de la pila de llamadas (que no sean el llamador inmediato) no necesitan permiso de código no administrado para ejecutar código no administrado. En función de las acciones y el control de entrada del miembro público, podría permitir que los autores de llamadas no confiables accedan a la funcionalidad normalmente restringida al código de confianza.

.NET se basa en comprobaciones de seguridad para evitar que los autores de llamadas obtengan acceso directo al espacio de direcciones del proceso actual. Dado que este atributo omite la seguridad normal, el código supone una amenaza grave si se puede usar para leer o escribir en la memoria del proceso. Tenga en cuenta que el riesgo no se limita a los métodos que proporcionan de forma intencionada el acceso a la memoria del proceso; también está presente en cualquier escenario en el que el código malintencionado pueda obtener acceso por cualquier medio, por ejemplo, proporcionando entradas sorprendentes, con formato incorrecto o no válidas.

La directiva de seguridad predeterminada no concede permiso de código no administrado a un ensamblado a menos que se ejecute desde el equipo local o sea miembro de uno de los siguientes grupos:

  • Mi grupo de código de zona de equipo

  • Grupo de código de nombre seguro de Microsoft

  • Grupo de código de nombre seguro de ECMA

Cómo corregir infracciones

Revise cuidadosamente el código para asegurarse de que este atributo es absolutamente necesario. Si no está familiarizado con la seguridad del código administrado o no entiende las implicaciones de seguridad de usar este atributo, quítelo del código. Si el atributo es necesario, debe asegurarse de que los autores de llamadas no puedan usar el código de forma malintencionada. Si el código no tiene permiso para ejecutar código no administrado, este atributo no tiene ningún efecto y debe quitarse.

Cuándo suprimir las advertencias

Para suprimir de forma segura una advertencia de esta regla, debe asegurarse de que el código no proporciona a los autores de llamadas acceso a operaciones nativas o recursos que se pueden usar de forma destructiva.

Ejemplo 1

En el ejemplo siguiente se infringe esta regla.

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.
      }
   }
}

Ejemplo 2

En el ejemplo siguiente, el método DoWork proporciona una ruta de acceso de código accesible públicamente al método FormatHardDisk de invocación de plataforma.

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();
      }
   }
}

Ejemplo 3

En el ejemplo siguiente, el método público DoDangerousThing provoca una infracción. Para resolver la infracción, DoDangerousThing debe ser privado y el acceso a él debe ser a través de un método público protegido por una demanda de seguridad, como se muestra en el método DoWork.

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();
      }
   }
}

Consulte también