Problèmes de sécurité dans l'émission de réflexion
Le .NET Framework offre trois manières d'émettre le langage MSIL (Microsoft Intermediate Language), chacune présentant ses propres problèmes de sécurité :
Assemblys dynamiques
Méthodes dynamiques hébergées de manière anonyme
Méthodes dynamiques associées aux assemblys existants
Quelle que soit la manière dont vous générez le code dynamique, l'exécution du code généré nécessite toutes les autorisations requises par les types et méthodes utilisés par le code généré.
Remarque |
---|
Les autorisations requises pour refléter et émettre du code ont changé avec l'évolution des versions du .NET Framework.Consultez Informations de version, plus loin dans cette rubrique. |
Assemblys dynamiques
Les assemblys dynamiques sont créés en utilisant des surcharges de la méthode AppDomain.DefineDynamicAssembly. La plupart des surcharges de cette méthode sont déconseillées par le .NET Framework version 4, à cause de l'élimination de la stratégie de sécurité au niveau de l'ordinateur. (Consultez Modifications de sécurité dans le .NET Framework 4.) Les surcharges restantes peuvent être exécutées par n'importe quel code, indépendamment du niveau de confiance. Ces surcharges sont réparties en deux groupes : celles qui spécifient une liste d'attributs à appliquer à l'assembly dynamique lors de sa création, et celles qui n'en spécifient pas. Si vous ne spécifiez pas le modèle de transparence pour l'assembly en appliquant l'attribut SecurityRulesAttribute lors de sa création, le modèle de transparence est hérité de l'assembly émetteur.
Remarque |
---|
Les attributs que vous appliquez à l'assembly dynamique après sa création à l'aide de la méthode SetCustomAttribute ne sont pas appliqués tant que l'assembly n'est pas enregistré sur le disque et de nouveau chargé en mémoire. |
Le code d'un assembly dynamique peut accéder aux membres et aux types visibles d'autres assemblys.
Remarque |
---|
Les assemblys dynamiques n'utilisent pas les indicateurs ReflectionPermissionFlag.MemberAccess et ReflectionPermissionFlag.RestrictedMemberAccess qui permettent aux méthodes dynamiques d'accéder aux membres et types non publics. |
Les assemblys dynamiques transitoires sont créés en mémoire et jamais enregistrés sur le disque ; ils ne requièrent donc aucune autorisation d'accès au fichier. L'enregistrement d'un assembly dynamique sur le disque requiert FileIOPermission avec les indicateurs appropriés.
Génération d'assemblys dynamiques à partir de code d'un niveau de confiance partiel
Considérez les conditions dans lesquelles un assembly disposant d'autorisations Internet peut générer un assembly dynamique transitoire et exécuter son code :
L'assembly dynamique utilise uniquement des membres et types publics d'autres assemblys.
Les autorisations demandées par ces types et membres sont incluses dans le jeu d'autorisations de l'assembly doté d'une confiance partielle.
L'assembly n'est pas enregistré sur le disque.
Les symboles de débogage ne sont pas générés. (les jeux d'autorisations Internet et LocalIntranet n'incluent pas les autorisations nécessaires)
Méthodes dynamiques hébergées de manière anonyme
Les méthodes dynamiques hébergées de manière anonyme sont créées à l'aide des deux constructeurs DynamicMethod qui ne spécifient pas un module ou un type associé, DynamicMethod(String, Type, Type[]) et DynamicMethod(String, Type, Type[], Boolean). Ces constructeurs placent les méthodes dynamiques dans un assembly fourni par le système, d'un niveau de confiance suffisant et Security Transparent. Aucune autorisation n'est requise pour utiliser ces constructeurs ou émettre du code pour les méthodes dynamiques.
À la place, lorsqu'une méthode dynamique hébergée de manière anonyme est créée, la pile des appels est capturée. Lorsque la méthode est construite, des demandes de sécurité sont effectuées auprès de la pile des appels capturée.
Remarque |
---|
Conceptuellement, les demandes sont faites pendant la construction de la méthode.Autrement dit, les demandes pourraient être faites lors de l'émission de chaque instruction MSIL.Dans l'implémentation actuelle, toutes les demandes sont faites lorsque la méthode DynamicMethod.CreateDelegate est appelée ou lorsque le compilateur juste-à-temps (JIT, Just-In-Time) est appelé, si la méthode est appelée sans appeler CreateDelegate. |
Si le domaine d'application le permet, les méthodes dynamiques hébergées de manière anonyme peuvent ignorer les contrôles de visibilité JIT, compte tenu des restrictions suivantes : les membres et types non publics accessibles par une méthode dynamique hébergée de manière anonyme doivent se trouver dans des assemblys dont les jeux d'autorisations sont des sous-ensembles ou sont équivalents au jeu d'autorisations de la pile des appels émettrice. Cette capacité restreinte permettant d'ignorer des contrôles de visibilité JIT est activée si le domaine d'application accorde à ReflectionPermission l'indicateur ReflectionPermissionFlag.RestrictedMemberAccess.
Si votre méthode utilise uniquement des membres et types publics, aucune autorisation n'est requise pendant la construction.
Si vous spécifiez que les contrôles de visibilité JIT doivent être ignorés, la demande faite lorsque la méthode est construite inclut ReflectionPermission avec l'indicateur ReflectionPermissionFlag.RestrictedMemberAccess et le jeu d'autorisations de l'assembly contenant le membre non public faisant l'objet d'un accès.
Étant donné que le jeu d'autorisations du membre non public est pris en considération, le code d'un niveau de confiance partiel auquel ReflectionPermissionFlag.RestrictedMemberAccess a été accordé ne peut pas élever ses privilèges en exécutant des membres non publics d'assemblys de confiance.
Comme pour tout autre code émis, l'exécution de la méthode dynamique requiert toutes les autorisations demandées par les méthodes que la méthode dynamique utilise.
L'assembly système qui héberge des méthodes dynamiques hébergées de manière anonyme utilise le modèle de transparence SecurityRuleSet.Level1, qui est le modèle de transparence utilisé dans les versions du .NET Framework antérieures au .NET Framework 4.
Pour plus d'informations, consultez la classe DynamicMethod.
Génération de méthodes dynamiques hébergées de manière anonyme à partir de code d'un niveau de confiance partiel
Considérez les conditions dans lesquelles un assembly avec des autorisations Internet peut générer et exécuter une méthode dynamique hébergée de manière anonyme :
La méthode dynamique utilise uniquement des membres et des types publics. Si son jeu d'autorisations inclut ReflectionPermissionFlag.RestrictedMemberAccess, elle peut utiliser des membres et des types non publics de tout assembly dont le jeu d'autorisations est un sous-ensemble ou est égal au jeu d'autorisations de l'assembly émetteur.
Les autorisations requises par tous les types et membres utilisés par la méthode dynamique sont incluses dans le jeu d'autorisations de l'assembly doté d'une confiance partielle.
Remarque |
---|
Les méthodes dynamiques ne prennent pas en charge les symboles de débogage. |
Méthodes dynamiques associées aux assemblys existants
Pour associer une méthode dynamique à un type ou à un module dans un assembly existant, utilisez l'un des constructeurs DynamicMethod qui spécifient le module ou le type associé. Les autorisations requises pour appeler ces constructeurs varient, car l'association d'une méthode dynamique à un module ou type existant permet à la méthode dynamique d'accéder aux membres et types non publics :
Une méthode dynamique associée à un type peut accéder à tous les membres de ce type, même aux membres privés, et à tous les membres et types internes de l'assembly qui contient le type associé.
Une méthode dynamique associée à un module peut accéder à tous les membres et types internal (Friend en Visual Basic, assembly dans les métadonnées CLR) du module.
De plus, vous pouvez utiliser un constructeur qui spécifie la possibilité d'ignorer les contrôles de visibilité du compilateur JIT. Ainsi, votre méthode dynamique peut accéder à tous les types et membres de tous les assemblys, quel que soit le niveau d'accès.
Les autorisations demandées par le constructeur dépendent du type d'accès que vous décidez de donner à votre méthode dynamique :
Si votre méthode utilise uniquement des membres et des types publics et si vous l'associez à votre propre type ou module, aucune autorisation n'est requise.
Si vous spécifiez que les contrôles de visibilité JIT doivent être ignorés, le constructeur demande ReflectionPermission avec l'indicateur ReflectionPermissionFlag.MemberAccess.
Si vous associez la méthode dynamique à un autre type, même un autre type de votre propre assembly, le constructeur demande ReflectionPermission avec l'indicateur ReflectionPermissionFlag.MemberAccess et SecurityPermission avec l'indicateur SecurityPermissionFlag.ControlEvidence.
Si vous associez la méthode dynamique à un type ou module d'un autre assembly, le constructeur demande deux éléments : ReflectionPermission avec l'indicateur ReflectionPermissionFlag.RestrictedMemberAccess, et le jeu d'autorisations de l'assembly qui contient l'autre module. Autrement dit, votre pile d'appels doit inclure toutes les autorisations dans le jeu d'autorisations du module cible, plus ReflectionPermissionFlag.RestrictedMemberAccess.
Remarque Pour une compatibilité descendante, si la demande pour le jeu d'autorisations cible plus ReflectionPermissionFlag.RestrictedMemberAccess échoue, le constructeur demande SecurityPermission avec l'indicateur SecurityPermissionFlag.ControlEvidence.
Bien que les éléments de cette liste soient décrits par rapport au jeu d'autorisations de l'assembly émetteur, n'oubliez pas que les demandes sont faites auprès de la pile des appels complète, y compris la limite de domaine d'application.
Pour plus d'informations, consultez la classe DynamicMethod.
Génération de méthodes dynamiques à partir de code d'un niveau de confiance partiel
Remarque |
---|
La méthode recommandée pour générer des méthodes dynamiques à partir de code d'un niveau de confiance partiel consiste à utiliser des méthodes dynamiques hébergées de manière anonyme. |
Considérez les conditions dans lesquelles un assembly disposant d'autorisations Internet peut générer une méthode dynamique et l'exécuter :
Soit la méthode dynamique est associée au module ou au type qui l'émet, soit son jeu d'autorisations inclut ReflectionPermissionFlag.RestrictedMemberAccess et est associé à un module dans un assembly dont le jeu d'autorisations est un sous-ensemble ou est égal au jeu d'autorisations de l'assembly émetteur.
La méthode dynamique utilise uniquement des membres et des types publics. Si son jeu d'autorisations inclut ReflectionPermissionFlag.RestrictedMemberAccess et est associé à un module dans un assembly dont le jeu d'autorisations est un sous-ensemble ou est égal au jeu d'autorisations de l'assembly émetteur, il peut utiliser les types et membres marqués internal (Friend en Visual Basic, assembly dans les métadonnées CLR) dans le module associé.
Les autorisations demandées par tous les types et membres utilisés par la méthode dynamique sont incluses dans le jeu d'autorisations de l'assembly doté d'une confiance partielle.
La méthode dynamique n'ignore pas les contrôles de visibilité JIT.
Remarque |
---|
Les méthodes dynamiques ne prennent pas en charge les symboles de débogage. |
Informations de version
À partir du .NET Framework 4, la stratégie de sécurité au niveau de l'ordinateur est éliminée et la transparence de sécurité devient le mécanisme de mise en application par défaut. Consultez Modifications de sécurité dans le .NET Framework 4.
Avec .NET Framework version 2.0 Service Pack 1, ReflectionPermission avec l'indicateur ReflectionPermissionFlag.ReflectionEmit n'est plus nécessaire lors de l'émission d'assemblys dynamiques et de méthodes dynamiques. Cet indicateur est requis dans toutes les versions antérieures du .NET Framework.
Remarque |
---|
ReflectionPermission avec l'indicateur ReflectionPermissionFlag.ReflectionEmit est inclus par défaut dans les jeux d'autorisations nommés FullTrust et LocalIntranet, mais pas dans le jeu d'autorisations Internet.Par conséquent, dans les versions antérieures du .NET Framework, une bibliothèque peut être utilisée avec des autorisations Internet uniquement si elle exécute un Assert pour ReflectionEmit.Ces bibliothèques nécessitent une révision de sécurité approfondie car les erreurs de codage pourraient provoquer des failles de sécurité..NET Framework 2.0 SP1 autorise l'émission de code dans des scénarios de confiance partielle sans émission de demandes de sécurité, parce que la génération du code n'est pas fondamentalement une opération privilégiée.Autrement dit, le code généré n'a pas plus d'autorisations que l'assembly qui l'émet.Cela permet aux bibliothèques qui émettent du code d'être Security Transparent et évite d'avoir à déclarer ReflectionEmit, ce qui simplifie l'écriture d'une bibliothèque sécurisée. |
De plus, .NET Framework 2.0 SP1 présente l'indicateur ReflectionPermissionFlag.RestrictedMemberAccess pour accéder aux membres et types non publics des méthodes dynamiques dotées d'une confiance partielle. Les versions antérieures du .NET Framework requièrent l'indicateur ReflectionPermissionFlag.MemberAccess pour les méthodes dynamiques qui accèdent à des membres et types non publics ; cette autorisation ne doit jamais être accordée au code d'un niveau de confiance partiel.
Enfin, .NET Framework 2.0 SP1 présente des méthodes hébergées de manière anonyme.
Obtention d'informations sur les types et les membres
Avec .NET Framework 2.0, aucune autorisation n'est requise pour obtenir des informations sur les membres et types non publics. La réflexion est utilisée pour obtenir les informations nécessaires à l'émission de méthodes dynamiques. Par exemple, les objets MethodInfo sont utilisés pour émettre des appels de méthode. Les versions antérieures du .NET Framework requièrent ReflectionPermission avec l'indicateur ReflectionPermissionFlag.TypeInformation. Pour plus d'informations, consultez Considérations sur la sécurité de la réflexion.
Voir aussi
Concepts
Considérations sur la sécurité de la réflexion