La sécurité de la méthode doit être un sur-ensemble du type
Mise à jour : novembre 2007
TypeName |
MethodSecurityShouldBeASupersetOfType |
CheckId |
CA2114 |
Catégorie |
Microsoft.Security |
Modification avec rupture |
Oui |
Cause
Un type présente une sécurité déclarative, une de ses méthodes présente une sécurité déclarative pour la même action de sécurité, l'action de sécurité n'est pas Demandes de liaison ou Demandes d'héritage, et les autorisations vérifiées par le type ne constituent pas un sous-ensemble des autorisations vérifiées par la méthode.
Description de la règle
Pour une même action, une méthode ne doit pas présenter de sécurité déclarative à la fois au niveau méthode et au niveau type. Les deux contrôles ne sont pas combinés ; seule une demande de niveau méthode s'applique. Par exemple, si un type demande une autorisation X et que l'une de ses méthodes demande une autorisation Y, le code n'a pas besoin de l'autorisation X pour exécuter la méthode.
Comment corriger les violations
Passez en revue votre code pour vous assurer que les deux actions sont requises. Si les deux actions sont requises, assurez-vous que l'action de niveau de méthode inclut la sécurité spécifiée au niveau type. Par exemple, si votre type demande une autorisation X, et si sa méthode doit également demander une autorisation Y, la méthode doit demander explicitement X et Y.
Quand supprimer les avertissements
Il est possible de supprimer sans risque un avertissement de cette règle si la méthode ne requiert pas la sécurité spécifiée par le type. Toutefois, ce scénario n'est pas ordinaire et peut indiquer la nécessité d'un examen approfondi du design.
Exemple
L'exemple suivant utilise des autorisations d'environnement pour montrer les dangers liés à la violation de cette règle. Dans cet exemple, le code d'application crée une instance du type sécurisé avant de refuser l'autorisation requise par le type. Dans un scénario de menace réel, l'application impliquerait une autre manière d'obtenir une instance de l'objet.
Dans l'exemple suivant, la bibliothèque demande une autorisation d'écriture pour un type et une autorisation de lecture pour une méthode.
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");
}
}
}
Le code d'application suivant montre la vulnérabilité de la bibliothèque en appelant la méthode alors qu'il ne satisfait pas la configuration requise en matière de sécurité au niveau du type.
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)]");
}
}
}
Cet exemple génère la sortie suivante :
[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.