Udostępnij za pośrednictwem


CA2114: Metody zabezpieczeń powinny być nadzbiorem typu

Pozycja Wartość
Ruleid CA2114
Kategoria Microsoft.Security
Zmiana powodująca niezgodność Kluczowa

Przyczyna

Typ ma zabezpieczenia deklaratywne, a jedna z jego metod ma deklaratywne zabezpieczenia dla tej samej akcji zabezpieczeń, a akcja zabezpieczeń nie ma linków żądań, a uprawnienia sprawdzane przez typ nie są podzbiorem uprawnień sprawdzanych przez metodę.

Uwaga

Ta reguła została przestarzała. Aby uzyskać więcej informacji, zobacz Przestarzałe reguły.

Opis reguły

Metoda nie powinna mieć zarówno zabezpieczeń deklaratywnych na poziomie metody, jak i na poziomie typu dla tej samej akcji. Te dwie kontrole nie są łączone; stosowane jest tylko zapotrzebowanie na poziomie metody. Jeśli na przykład typ wymaga uprawnień , a jedna z jego metod wymaga uprawnieńXY, kod nie musi mieć uprawnień X do wykonania metody.

Jak naprawić naruszenia

Przejrzyj kod, aby upewnić się, że oba akcje są wymagane. Jeśli obie akcje są wymagane, upewnij się, że akcja na poziomie metody obejmuje zabezpieczenia określone na poziomie typu. Jeśli na przykład typ wymaga uprawnień X, a jej metoda musi również zażądać uprawnień Y, metoda powinna jawnie żądać X i Y.

Kiedy pomijać ostrzeżenia

Można bezpiecznie pominąć ostrzeżenie z tej reguły, jeśli metoda nie wymaga zabezpieczeń określonych przez typ. Jednak nie jest to zwykły scenariusz i może wskazywać na potrzebę starannego przeglądu projektu.

Przykład 1

W poniższym przykładzie użyto uprawnień środowiska, aby zademonstrować niebezpieczeństwa naruszenia tej reguły. W tym przykładzie kod aplikacji tworzy wystąpienie zabezpieczonego typu przed odmową uprawnienia wymaganego przez typ. W rzeczywistym scenariuszu zagrożenia aplikacja wymagałaby innego sposobu uzyskania wystąpienia obiektu.

W poniższym przykładzie biblioteka wymaga uprawnień do zapisu dla typu i uprawnienia do odczytu dla metody.

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

Przykład 2

Poniższy kod aplikacji demonstruje lukę w zabezpieczeniach biblioteki przez wywołanie metody, mimo że nie spełnia wymagań dotyczących zabezpieczeń na poziomie typu.

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

Ten przykład generuje następujące wyniki:

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

Zobacz też