Partager via


Problèmes de sécurité dans l'émission de réflexion

Mise à jour : novembre 2007

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. Les autorisations requises dépendent de la surcharge utilisée. Par exemple, les surcharges qui fournissent une preuve requièrent SecurityPermission avec l'indicateur SecurityPermissionFlag.ControlEvidence. Certaines surcharges ne requièrent pas d'autorisations et peuvent être appelées à partir d'un code disposant uniquement d'autorisations Internet.

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.

La génération de code avec des symboles de débogage requiert ReflectionPermission avec l'indicateur ReflectionPermissionFlag.ReflectionEmit.

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.

  • La surcharge de méthode DefineDynamicAssembly utilisée pour créer l'assembly dynamique ne requiert pas d'autorisations spéciales (autrement dit, aucune preuve n'est fournie, etc.).

  • 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 l'indicateur ReflectionPermissionFlag.ReflectionEmit.)

Établissement d'autorisations pour les assemblys dynamiques

Dans la liste suivante, « émetteur » est l'assembly qui génère l'assembly dynamique.

  • Un émetteur disposant de SecurityPermission avec l'indicateur SecurityPermissionFlag.ControlEvidence peut fournir une preuve pour le code généré. Cette preuve est mappée via une stratégie pour déterminer les autorisations accordées.

  • Un émetteur peut fournir une preuve nulle, auquel cas l'assembly obtient le jeu d'autorisations de l'émetteur. Cela garantit que le code généré ne possède pas plus d'autorisations que son émetteur.

  • Si vous fournissez des jeux d'autorisations avec SecurityAction.RequestMinimum, SecurityAction.RequestOptional ou SecurityAction.RequestRefuse, ces jeux d'autorisations ne sont pas utilisés tant que l'assembly n'a pas été enregistré sur le disque, puis chargé à partir du disque.

  • Lorsqu'un assembly dynamique a été enregistré sur le disque, l'assembly est traité comme tout autre assembly chargé à partir du disque.

  • Le code généré par des émetteurs d'un niveau de confiance moyen est toujours vérifié. En particulier, le runtime vérifie toujours le code qui ne possède pas SecurityPermission avec l'indicateur SecurityPermissionFlag.SkipVerification. Les émetteurs d'un niveau de confiance suffisant peuvent ignorer la vérification ou demander que le code généré soit vérifié.

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, array<Type[]) et DynamicMethod(String, Type, array<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.

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 égaux au jeu d'autorisations de la pile des appels émettrice. Cette capacité restreinte d'ignorer les contrôles de visibilité JIT requiert ReflectionPermission avec 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.

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 dans 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 :

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 dans 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

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.

Pour utiliser ces fonctionnalités, votre application doit cibler le .NET Framework version 3.5. Pour plus d'informations, consultez Architecture de .NET Framework 3.5.

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

Autres ressources

Émission d'assemblys et de méthodes dynamiques