Partager via


Problèmes de sécurité liés à Reflection Emit

.NET Framework fournit trois façons d’émettre un langage intermédiaire commun (CIL), chacun avec ses propres problèmes de sécurité :

Quelle que soit la façon dont vous générez du code dynamique, l’exécution du code généré nécessite toutes les autorisations requises par les types et méthodes que le code généré utilise.

Remarque

Les autorisations requises pour refléter le code et l’émission de code ont changé avec les versions successives de .NET Framework. Consultez les informations de version, plus loin dans cet article.

Assemblages dynamiques

Les assemblys dynamiques sont créés à l'aide de surcharges de la méthode AppDomain.DefineDynamicAssembly. La plupart des surcharges de cette méthode sont déconseillées dans .NET Framework 4, en raison de l’élimination de la stratégie de sécurité à l’échelle de l’ordinateur. Les surcharges restantes peuvent être exécutées par n’importe quel code, quel que soit le niveau d’approbation. Ces surcharges appartiennent à deux groupes : celles qui spécifient une liste d’attributs à appliquer à l’assembly dynamique lors de sa création, et celles qui ne le font pas. Si vous ne spécifiez pas le modèle de transparence pour l’assembly, en appliquant l’attribut SecurityRulesAttribute lorsque vous le créez, 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, ne prennent pas effet tant que l’assembly n’a pas été enregistré sur le disque et chargé à nouveau dans la SetCustomAttribute mémoire.

Le code d’un assembly dynamique peut accéder aux types visibles et aux membres d’autres assemblys.

Remarque

Les assemblages dynamiques n’utilisent pas les indicateurs ReflectionPermissionFlag.MemberAccess et ReflectionPermissionFlag.RestrictedMemberAccess qui permettent aux méthodes dynamiques d’accéder aux types et membres privés.

Les assemblys dynamiques temporaires sont créés en mémoire et n’ont jamais été enregistrés sur le disque. Ils ne nécessitent donc aucune autorisation d’accès aux fichiers. L’enregistrement d’un assembly dynamique sur le disque nécessite FileIOPermission avec les indicateurs appropriés.

Génération d’assemblys dynamiques à partir d’un code partiellement approuvé

Tenez compte des conditions dans lesquelles un assembly disposant d’autorisations Internet peut générer un assembly dynamique temporaire et exécuter son code :

  • L'assembly dynamique utilise seulement des types et des membres publics d'autres assemblys.

  • Les autorisations demandées par ces types et ces membres sont incluses dans le jeu d'autorisations de l'assembly partiellement approuvé.

  • L'assemblage n'est pas sauvegardé sur le disque.

  • Les symboles de débogage ne sont pas générés. (Internet et LocalIntranet sont des jeux d’autorisations qui n’incluent pas les autorisations nécessaires.)

Méthodes dynamiques hébergées anonymement

Les méthodes dynamiques hébergées anonymement sont créées à l’aide des deux DynamicMethod constructeurs qui ne spécifient pas de type ou de module 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, entièrement fiable et transparent quant à la sécurité. Aucune autorisation n’est requise pour utiliser ces constructeurs ou émettre du code pour les méthodes dynamiques.

Au lieu de cela, lorsqu’une méthode dynamique hébergée anonymement est créée, la pile des appels est capturée. Lorsque la méthode est construite, les demandes de sécurité sont effectuées sur la pile d’appels capturée.

Remarque

Conceptuellement, les demandes sont faites durant l'élaboration de la méthode. C’est-à-dire que les demandes peuvent être effectuées au fur et à mesure que chaque instruction CIL est émise. Dans l'implémentation actuelle, toutes les demandes sont faites quand la méthode DynamicMethod.CreateDelegate est appelée ou quand le compilateur juste-à-temps (JIT) est appelé, si la méthode est appelée sans appel de CreateDelegate.

Si le domaine d’application l’autorise, les méthodes dynamiques hébergées anonymement peuvent ignorer les vérifications de visibilité JIT, sous réserve de la restriction suivante : Les types et membres non publics accessibles par une méthode dynamique hébergée anonymement doivent se trouver dans des assemblys dont les jeux d’octroi sont égaux ou sous-ensembles de la pile d’appels émettrices. Cette possibilité restreinte d'ignorer les contrôles de visibilité JIT est activée si le domaine d'application accorde l'autorisation ReflectionPermission avec l'indicateur ReflectionPermissionFlag.RestrictedMemberAccess.

  • Si votre méthode utilise uniquement des types et des membres 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 qui est faite quand la méthode est construite inclut ReflectionPermission avec l'indicateur ReflectionPermissionFlag.RestrictedMemberAccess et le jeu d'autorisations de l'assembly qui contient le membre non public qui fait l'objet de l'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 l'autorisation ReflectionPermissionFlag.RestrictedMemberAccess a été accordée ne peut pas élever ses privilèges en exécutant des membres non publics d'assemblys approuvés.

Comme pour tout autre code émis, l’exécution de la méthode dynamique nécessite les autorisations demandées par les méthodes utilisées par la méthode dynamique.

L’assembly système qui héberge des méthodes dynamiques hébergées anonymement utilise le modèle de transparence, qui est le SecurityRuleSet.Level1 modèle de transparence utilisé dans .NET Framework avant .NET Framework 4.

Pour plus d’informations, consultez la DynamicMethod classe.

Génération de méthodes dynamiques hébergées anonymement à partir d’un code partiellement approuvé

Tenez compte des conditions dans lesquelles un assembly disposant d’autorisations Internet peut générer une méthode dynamique hébergée anonymement et l’exécuter :

  • La méthode dynamique utilise seulement des types et des membres publics. Si son ensemble d’autorisations inclut ReflectionPermissionFlag.RestrictedMemberAccess, il peut utiliser des types et des membres non publics de toute assemblée dont l’ensemble d’autorisations est égal ou un sous-ensemble de l’ensemble d’autorisations de l’assemblée émettrice.

  • Les autorisations requises par tous les types et les membres utilisés par la méthode dynamique sont incluses dans le jeu d'autorisations de l'assembly partiellement approuvé.

Remarque

Les méthodes dynamiques ne prennent pas en charge les symboles de débogage.

Méthodes dynamiques associées à des assemblys existants

Pour associer une méthode dynamique à un type ou un module dans un assembly existant, utilisez l’un DynamicMethod des constructeurs qui spécifient le type ou le module associé. Les autorisations requises pour appeler ces constructeurs varient, car l’association d’une méthode dynamique à un type ou module existant donne à la méthode dynamique l’accès aux types et membres non publics :

  • Une méthode dynamique associée à un type a accès à tous les membres de ce type, même aux membres privés, ainsi qu’à tous les types et membres internes de l’assembly qui contient le type associé.

  • Une méthode dynamique associée à un module a accès à tous les internal types et membres (Friend en Visual Basic, assembly dans les métadonnées common language runtime) dans le module.

En outre, vous pouvez utiliser un constructeur qui spécifie la possibilité d’ignorer les vérifications de visibilité du compilateur JIT. Cela permet à votre méthode dynamique d’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 de la quantité d’accès que vous décidez de donner à votre méthode dynamique :

Bien que les éléments de cette liste soient décrits en les termes du jeu d'autorisations de l'assembly émetteur, n'oubliez pas que les demandes sont faites sur la pile des appels complète, y compris la limite du domaine de l'application.

Pour plus d’informations, consultez la DynamicMethod classe.

Génération de méthodes dynamiques à partir d’un code partiellement approuvé

Remarque

La méthode recommandée pour générer des méthodes dynamiques à partir de code partiellement approuvé consiste à utiliser des méthodes dynamiques hébergées anonymement.

Tenez compte des conditions dans lesquelles un assembly disposant d’autorisations Internet peut générer une méthode dynamique et l’exécuter :

  • La méthode dynamique est associée au module ou au type qui l’émet, ou son jeu d’octroi inclut ReflectionPermissionFlag.RestrictedMemberAccess et il est associé à un module dans un assembly dont le jeu d’octroi est égal ou à un sous-ensemble de l’assembly émetteur.

  • La méthode dynamique utilise seulement des types et des membres publics. Si son jeu d’octroi inclut ReflectionPermissionFlag.RestrictedMemberAccess et qu’il est associé à un module dans un assembly dont le jeu d’autorisations est égal ou à un sous-ensemble, le jeu d’octroi de l’assembly émetteur, il peut utiliser des types et des membres marqués internal (Friend en Visual Basic, assembly dans les métadonnées common language runtime) dans le module associé.

  • Les autorisations demandées par tous les types et les membres utilisés par la méthode dynamique sont incluses dans le jeu d'autorisations de l'assembly partiellement approuvé.

  • 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 sur la version

À compter de .NET Framework 4, la stratégie de sécurité à l’échelle de l’ordinateur est éliminée et la transparence de la sécurité devient le mécanisme d’application par défaut.

À compter de .NET Framework 2.0 Service Pack 1, ReflectionPermission avec l’indicateur ReflectionPermissionFlag.ReflectionEmit n’est plus nécessaire lors de l’émission d’assemblys et de méthodes dynamiques. Cet indicateur est requis dans toutes les versions antérieures de .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 de .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 un examen de sécurité prudent, car les erreurs de codage peuvent entraîner des trous de sécurité. .NET Framework 2.0 SP1 permet au code d’être émis dans des scénarios d’approbation partielle sans émettre de demandes de sécurité, car la génération du code n’est pas intrinsèquement 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 transparentes en matière de sécurité et supprime la nécessité d’affirmer ReflectionEmit, ce qui simplifie la tâche d’écriture d’une bibliothèque sécurisée.

De plus, .NET Framework 2.0 SP1 introduit l’indicateur ReflectionPermissionFlag.RestrictedMemberAccess permettant d’accéder aux types et membres non publics à partir de méthodes dynamiques partiellement approuvées. Les versions antérieures du .NET Framework nécessitent l’indicateur ReflectionPermissionFlag.MemberAccess pour les méthodes dynamiques qui accèdent aux types et membres non publics ; il s’agit d’une autorisation qui ne doit jamais être accordée au code partiellement approuvé.

Enfin, .NET Framework 2.0 SP1 introduit des méthodes hébergées anonymement.

Obtention d’informations sur les types et les membres

À compter de .NET Framework 2.0, aucune autorisation n’est requise pour obtenir des informations sur les types et les membres non publics. La réflexion est utilisée pour obtenir des informations nécessaires pour émettre des méthodes dynamiques. Par exemple, MethodInfo les objets sont utilisés pour émettre des appels de méthode. Les versions antérieures de .NET Framework nécessitent ReflectionPermission avec l’indicateur ReflectionPermissionFlag.TypeInformation. Pour plus d’informations, consultez Considérations relatives à la sécurité pour la réflexion.

Voir aussi