Compartir a través de


CA2114: La seguridad del método debería ser un supraconjunto del tipo

Nombre de tipo

MethodSecurityShouldBeASupersetOfType

Identificador de comprobación

CA2114

Categoría

Microsoft.Security

Cambio problemático

Causa

Un tipo tiene seguridad declarativa y uno de sus métodos dispone de seguridad declarativa para la misma acción de seguridad, y ésta no es Peticiones de vínculos ni Peticiones de herencia y, además, los permisos comprobados por el tipo no son un subconjunto de permisos comprobados por el método.

Descripción de la regla

Un método no debe tener un nivel de método ni un nivel de tipo seguridad declarativa para la misma acción. No se combinan las dos comprobaciones; sólo se aplica la solicitud de nivel de método. Por ejemplo, si un tipo solicita un permiso X y uno de sus métodos solicita un permiso Y, el código no necesita el permiso X para ejecutar el método.

Cómo corregir infracciones

Revise su código para asegurase de que ambas acciones son necesarias. Si son necesarias, asegúrese de que la acción de nivel de método incluye la seguridad especificada en el nivel de tipo. Por ejemplo, si el tipo solicita el permiso X y su método también debe solicitar el permiso Y, el método debe solicitar explícitamente X y Y.

Cuándo suprimir advertencias

Es seguro suprimir una advertencia de esta regla si el método no necesita la seguridad especificada por el tipo. Sin embargo, no se trata de un escenario común y podría indicar que es necesario revisar cuidadosamente el diseño.

Ejemplo

El ejemplo siguiente utiliza los permisos del entorno para mostrar los riesgos de infringir esta regla. En este ejemplo, el código de aplicación crea una instancia del tipo asegurado antes de denegar el permiso necesario por el tipo. En una situación de riesgo real, la aplicación necesitaría otra manera de obtener una instancia del objeto.

En el ejemplo siguiente, la biblioteca solicita permiso de escritura para un tipo y permiso de lectura para un método.

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

namespace SecurityRulesLibrary
{
   [EnvironmentPermissionAttribute(SecurityAction.Demand, Write="PersonalInfo")]
   public class MyClassWithTypeSecurity
   {
      [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
      [return:MarshalAs(UnmanagedType.Bool)]
      public static extern bool SetEnvironmentVariable(
         string lpName,
         string lpValue);

      // Constructor.
      public MyClassWithTypeSecurity(int year, int month, int day)
      {
         DateTime birthday = new DateTime(year, month, day);

         // Write out PersonalInfo environment variable.
         SetEnvironmentVariable("PersonalInfo",birthday.ToString());
      }

      [EnvironmentPermissionAttribute(SecurityAction.Demand, Read="PersonalInfo")]
      public string PersonalInformation ()
      { 
         // Read the variable.
         return Environment.GetEnvironmentVariable("PersonalInfo"); 
      }
   }
}

El código de aplicación siguiente muestra la vulnerabilidad de la biblioteca llamando al método aunque no cumple el nivel de tipo requisito de seguridad de nivel de tipo.

using System;
using System.Security;
using System.Security.Permissions;
using SecurityRulesLibrary;

namespace TestSecRulesLibrary
{
   public class TestMethodLevelSecurity
   {
      MyClassWithTypeSecurity dataHolder;

      void RetrievePersonalInformation(string description) 
      {
         try 
         { 
            Console.WriteLine(
               "{0} Personal information: {1}", 
               description, dataHolder.PersonalInformation());
         }
         catch (SecurityException e) 
         {
            Console.WriteLine(
               "{0} Could not access personal information: {1}", 
               description, e.Message);
         }
      }

      [STAThread]
      public static void Main() 
      {
         TestMethodLevelSecurity me = new TestMethodLevelSecurity();

         me.dataHolder = new MyClassWithTypeSecurity(1964,06,16);

         // Local computer zone starts with all environment permissions.
         me.RetrievePersonalInformation("[All permissions]");

         // Deny the write permission required by the type.
         EnvironmentPermission epw = new EnvironmentPermission(
            EnvironmentPermissionAccess.Write,"PersonalInfo");
         epw.Deny();

         // Even though the type requires write permission, 
         // and you do not have it; you can get the data.
         me.RetrievePersonalInformation(
            "[No write permission (demanded by type)]");

         // Reset the permissions and try to get 
         // data without read permission.
         CodeAccessPermission.RevertAll();  

         // Deny the read permission required by the method.
         EnvironmentPermission epr = new EnvironmentPermission(
            EnvironmentPermissionAccess.Read,"PersonalInfo");
         epr.Deny();

         // The method requires read permission, and you
         // do not have it; you cannot get the data.
         me.RetrievePersonalInformation(
            "[No read permission (demanded by method)]");
      }
   }
}

Este ejemplo produce el siguiente resultado.

  

Vea también

Conceptos

Instrucciones de codificación segura

Peticiones de herencia

Peticiones de vínculos

Otros recursos

Acceso a datos y modelado