Condividi tramite


CA2114: La sicurezza del metodo deve essere un superset del tipo

Articolo Valore
ID regola CA2114
Category Microsoft.Security
Modifica Interruzione

Causa

Un tipo dispone di sicurezza dichiarativa e uno dei relativi metodi dispone di sicurezza dichiarativa per la stessa azione di sicurezza e l'azione di sicurezza non è Richieste di collegamento e le autorizzazioni controllate dal tipo non sono un subset delle autorizzazioni controllate dal metodo .

Nota

Questa regola è stata deprecata. Per altre informazioni, vedere Regole deprecate.

Descrizione regola

Un metodo non deve avere sia una sicurezza dichiarativa a livello di metodo che a livello di tipo per la stessa azione. I due controlli non sono combinati; viene applicata solo la richiesta a livello di metodo. Ad esempio, se un tipo richiede l'autorizzazione Xe uno dei relativi metodi richiede l'autorizzazione Y, il codice non deve disporre dell'autorizzazione X per eseguire il metodo.

Come correggere le violazioni

Esaminare il codice per assicurarsi che siano necessarie entrambe le azioni. Se sono necessarie entrambe le azioni, assicurarsi che l'azione a livello di metodo includa la sicurezza specificata a livello di tipo. Ad esempio, se il tipo richiede l'autorizzazione Xe il relativo metodo deve anche richiedere l'autorizzazione Y, il metodo deve richiedere X in modo esplicito e Y.

Quando eliminare gli avvisi

È possibile eliminare un avviso da questa regola se il metodo non richiede la sicurezza specificata dal tipo. Tuttavia, questo non è uno scenario comune e potrebbe indicare una necessità di una revisione attenta della progettazione.

Esempio 1

Nell'esempio seguente vengono utilizzate le autorizzazioni di ambiente per dimostrare i pericoli di violazione di questa regola. In questo esempio, il codice dell'applicazione crea un'istanza del tipo protetto prima di negare l'autorizzazione richiesta dal tipo . In uno scenario di minaccia reale, l'applicazione richiederebbe un altro modo per ottenere un'istanza dell'oggetto.

Nell'esempio seguente la libreria richiede l'autorizzazione di scrittura per un tipo e l'autorizzazione di lettura per un metodo.

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

Esempio 2

Il codice dell'applicazione seguente illustra la vulnerabilità della libreria chiamando il metodo anche se non soddisfa il requisito di sicurezza a livello di 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)]");
      }
   }
}

Nell'esempio viene prodotto l'output seguente:

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

Vedi anche