CA2114: Metody zabezpieczeń powinny być nadzbiorem typu
TypeName |
MethodSecurityShouldBeASupersetOfType |
CheckId |
CA2114 |
Kategoria |
Microsoft.Security |
Zmiana kluczowa |
Kluczowa |
Przyczyna
Typ ma zabezpieczenia deklaracyjne, jedna z jego metod ma zabezpieczenia deklaracyjne dla tej samej akcji zabezpieczeń, akcja zabezpieczeń nie jest Żądania połączeń lub Żądania dziedziczenia i uprawnienia sprawdzane przez typ nie są podzbiorem uprawnień sprawdzonych przez metodę.
Opis reguły
Metoda nie powinna mieć zabezpieczeń deklaratywnych zarówno na poziomie metody i na poziomie typu dla tej samej akcji.Dwa sprawdzania nie są połączone; stosowana jest tylko żądanie na poziomie metody.Na przykład, jeśli typ wymaga uprawnień X i jedna z jego metod wymaga uprawnień Y, kod nie musi mieć uprawnień X do wykonania metody.
Jak naprawić naruszenia
Przejrzyj kod, aby upewnić się, że obie akcje są wymagane.Jeśli obie akcje są wymagane, upewnij się, że działania na poziomie metody zawierają określone zabezpieczenia na poziomie typu.Na przykład, jeśli typ sieci wymaga uprawnień X i jego metoda również wymagać uprawnienia Y, metoda powinna jawnie wymagać X i Y.
Kiedy pominąć ostrzeżenia
Można bezpiecznie pominąć ostrzeżenie od tej reguły, jeśli metoda nie wymaga zabezpieczeń określonych przez typ.Jednak to nie jest typowy scenariusz i może wskazywać na potrzebę uważnego przeglądu projektu.
Przykład
Poniższy przykład używa uprawnień środowiska, aby pokazać niebezpieczeństwa związane z naruszeniem tej zasady.W tym przykładzie kodu aplikacji tworzy wystąpienie zabezpieczonego typu przed odmówieniem uprawnień wymaganych przez typ.W rzeczywistym scenariuszu, aplikacja wymagałoby innego sposobu do uzyskania wystąpienia obiektu.
W poniższym przykładzie, biblioteka żąda uprawnienie zapisu dla typu i 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");
}
}
}
Poniższy kod aplikacji demonstruje luki w zabezpieczeniach biblioteki przez wywołanie metody, nawet jeśli nie spełnia wymagań 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.