CA2114: La seguridad del método debe ser un supraconjunto del tipo

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

Causa

Un tipo tiene seguridad declarativa y uno de sus métodos tiene seguridad declarativa para la misma acción de seguridad, y la acción de seguridad no es Link Demand y los permisos comprobados por el tipo no son un subconjunto de los permisos comprobados por el método.

Nota

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

Descripción de la regla

Un método no debe tener seguridad declarativa en el nivel de método y de tipo para la misma acción. Las dos comprobaciones no se combinan; solo se aplica la demanda de nivel de método. Por ejemplo, si un tipo exige permiso X y uno de sus métodos exige permiso Y, el código no tiene que tener permiso X para ejecutar el método.

Cómo corregir infracciones

Revise el código para asegurarse de que se requieren ambas acciones. Si se requieren ambas acciones, 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 exige permiso X y su método también debe exigir el permiso Y, el método debe exigir explícitamente X y Y.

Cuándo suprimir las advertencias

Es seguro suprimir una advertencia de esta regla si el método no requiere la seguridad especificada por el tipo. Sin embargo, esto no es un escenario normal y podría indicar que sería necesario realizar una revisión cuidadosa del diseño.

Ejemplo 1

En el ejemplo siguiente se usan permisos de entorno para demostrar los peligros de infringir esta regla. En este ejemplo, el código de aplicación crea una instancia del tipo protegido antes de denegar el permiso requerido por el tipo. En un escenario de amenazas real, la aplicación requeriría otra manera de obtener una instancia del objeto.

En el ejemplo siguiente, la biblioteca exige 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"); 
      }
   }
}

Ejemplo 2

El siguiente código de aplicación muestra la vulnerabilidad de la biblioteca llamando al método aunque no cumpla el 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:

[All permissions] Personal information: 6/16/1964 12:00:00 AM
[No write permission (demanded by type)] Personal information: 6/16/1964 12:00:00 AM
[No read permission (demanded by method)] Could not access personal information: Request failed.

Consulte también