Segurança de método deve ser um superconjunto de tipo
TypeName |
MethodSecurityShouldBeASupersetOfType |
CheckId |
CA2114 |
Category (Categoria) |
Microsoft.segurança |
Quebrando alterar |
Quebrando |
Causa
Um tipo de segurança declarativa tem e um de seus métodos tem segurança declarativa para a mesma ação de segurança e a ação de segurança não é Demandas de link ou Demandas de herança, e as permissões são verificadas pelo tipo não são um subconjunto das permissões são verificadas pelo método.
Descrição da regra
Um método não deve ter tanto uma segurança declarativa nível de método e nível do tipo para a mesma ação.Duas verificações não são combinadas; somente a demanda de nível de método é aplicada.Por exemplo, se um tipo de demandas de permissão X, e um de seus métodos exige permissão Y, código não precisa ter permissão X para executar o método.
Como corrigir violações
Revise seu código para certificar-se de que ambas as ações estão necessárias.Se ambas as ações forem necessárias, certifique-se de que a ação de nível de método inclui segurança especificada no nível do tipo.Por exemplo, se o seu tipo de demandas de permissão X, e seu método também deve solicitar permissão Y, o método deve solicitar explicitamente X e Y.
Quando suprimir avisos
É seguro eliminar um aviso essa regra se o método não exige a segurança especificada pelo tipo de.No entanto, isso não é um cenário comum e pode indicar a necessidade de uma revisão de design cuidadoso.
Exemplo
O exemplo a seguir usa as permissões de ambiente para demonstrar os perigos de violar a regra.Neste exemplo, o código do aplicativo cria uma instância do tipo protegido antes de negar a permissão exigida pelo tipo.Em um cenário de ameaças do mundo real, o aplicativo requer outra maneira de obter uma instância do objeto.
No exemplo a seguir, as solicitações de biblioteca de permissão de gravar para um tipo e permissão de leitura para um 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");
}
}
}
O seguinte código de aplicativo demonstra a vulnerabilidade da biblioteca, chamando o método mesmo que não atende ao requisito de segurança em nível 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)]");
}
}
}
O exemplo produz a seguinte saída.
[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.