Problemas de seguridad en la emisión de la reflexión
.NET Framework proporciona tres mecanismos para emitir el lenguaje intermedio de Microsoft (MSIL), cada uno con sus propios problemas de seguridad:
Ensamblados dinámicos
Métodos dinámicos hospedados de forma anónima
Métodos dinámicos asociados a ensamblados existentes
Con independencia del modo en que se genere el código dinámico, al ejecutar el código generado, es necesario disponer de los permisos requeridos por los tipos y métodos que el código generado utiliza.
Nota |
---|
Los permisos requeridos para la reflexión en código y la emisión de código han ido cambiando en las sucesivas versiones de .NET Framework.Vea la sección Información de versiones más adelante en este mismo tema. |
Ensamblados dinámicos
Los ensamblados dinámicos se crean con las sobrecargas del método AppDomain.DefineDynamicAssembly. La mayoría de las sobrecargas de este método están desusadas en .NET Framework versión 4 debido a la eliminación de la directiva de seguridad en el nivel de equipo. (Vea Cambios de seguridad en .NET Framework 4.) Las sobrecargas restantes las puede ejecutar cualquier código, independientemente del nivel de confianza. Estas sobrecargas se dividen en dos grupos: las que especifican una lista de atributos que se van a aplicar al ensamblado dinámico cuando se crea, y las que no la especifican. Si no se especifica el modelo de transparencia para el ensamblado y se aplica el atributo SecurityRulesAttribute en el momento de su creación, se heredará el modelo de transparencia del ensamblado emisor.
Nota |
---|
Cuando se utiliza método SetCustomAttribute, los atributos que se aplican al ensamblado dinámico después de su creación no surten efecto hasta que se guarda el ensamblado en el disco y se carga de nuevo en la memoria. |
El código de los ensamblados dinámicos puede obtener acceso a los tipos y miembros visibles de otros ensamblados.
Nota |
---|
Los ensamblados dinámicos no utilizan los marcadores ReflectionPermissionFlag.MemberAccess y ReflectionPermissionFlag.RestrictedMemberAccess, que permiten a los miembros dinámicos obtener acceso a tipos y miembros no públicos. |
Los ensamblados dinámicos transitorios se crean en memoria y nunca se guardan en disco, de modo que no necesitan ningún permiso de acceso a archivos. Si los ensamblados dinámicos se guardaran en el disco, se necesitarían permisos FileIOPermission con los marcadores adecuados.
Generar ensamblados dinámicos a partir de código de confianza parcial
Considere las condiciones en las que un ensamblado con permisos de Internet puede generar un ensamblado dinámico transitorio y ejecutar su código:
El ensamblado dinámico sólo utiliza tipos y miembros públicos de otros ensamblados.
Los permisos exigidos por esos tipos y miembros están incluidos en el conjunto de permisos concedidos del ensamblado de confianza parcial.
El ensamblado no está guardado en el disco.
No se generan símbolos de depuración. (Los conjuntos de permisos de Internet y LocalIntranet no incluyen los permisos necesarios).
Métodos dinámicos hospedados de forma anónima
Los métodos dinámicos hospedados de forma anónima se crean con dos constructores de DynamicMethod que no especifican ningún módulo o tipo asociado: DynamicMethod(String, Type, Type[]) y DynamicMethod(String, Type, Type[], Boolean). Estos constructores sitúan los métodos dinámicos en un ensamblado proporcionado por el sistema de plena confianza y transparente en seguridad. No es necesario ningún permiso para utilizar estos constructores o emitir código para los métodos dinámicos.
En su lugar, cuando se crea un método dinámico hospedado de forma anónima, se captura la pila de llamadas. Cuando se construye el método, las peticiones de seguridad se realizan en la pila de llamadas capturadas.
Nota |
---|
Conceptualmente, las peticiones se realizan durante la construcción del método.Es decir, las peticiones pueden realizarse cada vez que se emite una instrucción de MSIL.En la implementación actual, todas las peticiones se realizan cuando se llama al método DynamicMethod.CreateDelegate o cuando se invoca el compilador Just-In-Time (JIT), si el método se invoca sin llamar a CreateDelegate. |
Si el dominio de aplicación lo permite, los métodos dinámicos hospedados de forma anónima pueden omitir las comprobaciones de visibilidad JIT, con la restricción siguiente: los tipos y miembros no públicos a los que tienen acceso los métodos dinámicos hospedados de forma anónima deben estar en ensamblados cuyo conjunto de permisos concedidos sea igual que el conjunto de permisos concedidos de la pila de llamadas emisora (o un subconjunto de este). Esta capacidad restringida para omitir las comprobaciones de visibilidad JIT está habilitada si el dominio de aplicación concede ReflectionPermission con la marca ReflectionPermissionFlag.RestrictedMemberAccess.
Si el método sólo utiliza tipos y miembros públicos, no se requiere ningún permiso durante la construcción.
Si especifica que deben omitirse las comprobaciones de visibilidad JIT, la petición que se realiza cuando el método se construye incluye el permiso ReflectionPermission con el marcador ReflectionPermissionFlag.RestrictedMemberAccess y el conjunto de permisos concedidos del ensamblado que contiene el miembro no público al que se tiene acceso.
Dado que el conjunto de permisos concedidos del miembro no público se tiene en cuenta, el código de confianza parcial al que se le han concedido permisos ReflectionPermissionFlag.RestrictedMemberAccess no puede elevar sus privilegios ejecutando miembros no públicos de ensamblados de confianza.
Al igual que cualquier otro código emitido, al ejecutar el método dinámico, es necesario que los métodos que utiliza el método dinámico soliciten los permisos.
El ensamblado del sistema con métodos dinámicos hospedados de forma anónima utiliza el modelo de transparencia SecurityRuleSet.Level1, que es el modelo de transparencia que se utilizaba en las versiones de .NET Framework anteriores a .NET Framework 4.
Para obtener más información, vea la clase DynamicMethod.
Generar métodos dinámicos hospedados de forma anónima desde código de confianza parcial
Considere las condiciones en las que un ensamblado con permisos de Internet puede generar y ejecutar un método dinámico hospedado de forma anónima:
El método dinámico sólo utiliza tipos y miembros públicos. Si su conjunto de permisos concedidos incluye ReflectionPermissionFlag.RestrictedMemberAccess, puede utilizar tipos y miembros no públicos de cualquier ensamblado cuyo conjunto de permisos concedidos sea igual al conjunto de permisos concedidos del ensamblado emisor (o un subconjunto de éste).
Los permisos requeridos por todos los tipos y miembros que utiliza el método dinámico están incluidos en el conjunto de permisos concedidos del ensamblado de confianza parcial.
Nota |
---|
Los métodos dinámicos no admiten símbolos de depuración. |
Métodos dinámicos asociados a ensamblados existentes
Para asociar un método dinámico a un tipo o módulo de un ensamblado existente, utilice cualquiera de los constructores de DynamicMethod que especifican el tipo o módulo asociado. Los permisos requeridos para llamar a estos constructores varían, ya que al asociar un método dinámico con un tipo o módulo existente, el método dinámico obtiene acceso a tipos y miembros no públicos:
Un método dinámico que está asociado a un tipo tiene acceso a todos los miembros de ese tipo, incluidos los miembros privados, y a todos los tipos y miembros internos del ensamblado que contiene el tipo asociado.
Un método dinámico que está asociado a un módulo tiene acceso a todos los tipos y miembros internal (Friend en Visual Basic, assembly en los metadatos de Common Language Runtime) del módulo.
Además, puede utilizar un constructor que establezca la capacidad de omitir las comprobaciones de visibilidad del compilador JIT. De esto modo, el método dinámico obtendrá acceso a todos los tipos y miembros de todos los ensamblados, con independencia del nivel de acceso.
Los permisos exigidos por el constructor dependen del nivel de acceso que decida conceder al método dinámico:
Si su método sólo utiliza tipos y miembros públicos y lo asocia a un tipo o un módulo propio, no se requiere ningún permiso.
Si especifica que las comprobaciones de visibilidad JIT deben omitirse, el constructor exige el permiso ReflectionPermission con el marcador ReflectionPermissionFlag.MemberAccess.
Si asocia el método dinámico a otro tipo, incluso a otro tipo de su propio ensamblado, el constructor exige el permiso ReflectionPermission con el marcador ReflectionPermissionFlag.MemberAccess y el permiso SecurityPermission con el marcador SecurityPermissionFlag.ControlEvidence.
Si asocia el método dinámico a un tipo o módulo de otro ensamblado, el constructor exige dos cosas: el permiso ReflectionPermission con el marcador ReflectionPermissionFlag.RestrictedMemberAccess y el conjunto de permisos concedidos del ensamblado que contiene el otro módulo. Es decir, la pila de llamadas debe incluir todos los permisos del conjunto de permisos concedidos del módulo de destino, además del marcador ReflectionPermissionFlag.RestrictedMemberAccess.
Nota A efectos de compatibilidad con versiones anteriores, si la petición del conjunto de permisos concedidos junto con el marcador ReflectionPermissionFlag.RestrictedMemberAccess no se realiza correctamente, el constructor exige el permiso SecurityPermission con el marcador SecurityPermissionFlag.ControlEvidence.
Aunque los elementos de esta lista se describen en función del conjunto de permisos concedidos del ensamblado emisor, recuerde que las peticiones se realizan en la pila de llamadas completa, incluido el límite del dominio de aplicación.
Para obtener más información, vea la clase DynamicMethod.
Generar métodos dinámicos desde código de confianza parcial
Nota |
---|
La manera recomendada de generar los métodos dinámicos desde código de confianza parcial es utilizar métodos dinámicos hospedados de forma anónima. |
Considere las condiciones en las que un ensamblado con permisos de Internet puede generar un método dinámico y ejecutarlo:
O bien el método dinámico está asociado al módulo o al tipo que lo emite o bien su conjunto de permisos concedidos incluye ReflectionPermissionFlag.RestrictedMemberAccess y está asociado a un módulo de un ensamblado cuyo conjunto de permisos concedidos es igual que el conjunto de permisos concedidos del ensamblado emisor (o un subconjunto de éste).
El método dinámico sólo utiliza tipos y miembros públicos. Si su conjunto de permisos concedidos incluye ReflectionPermissionFlag.RestrictedMemberAccess y está asociado con un módulo de un ensamblado cuyo conjunto de permisos concedidos es igual al conjunto de permisos concedidos del ensamblado emisor (a un subconjunto de éste), puede usar los tipos y miembros marcados como internal (Friend en Visual Basic, assembly en los metadatos de Common Language Runtime) del módulo asociado.
Los permisos requeridos por todos los tipos y miembros que utiliza el método dinámico están incluidos en el conjunto de permisos concedidos del ensamblado de confianza parcial.
El método dinámico no omite las comprobaciones de visibilidad JIT.
Nota |
---|
Los métodos dinámicos no admiten símbolos de depuración. |
Información de versiones
A partir de .NET Framework 4, se elimina la directiva de seguridad en el nivel de equipo y la transparencia de seguridad pasa a ser el mecanismo de exigencia predeterminado. Vea Cambios de seguridad en .NET Framework 4.
Ya no es necesario empezar por el permiso .NET Framework versión 2.0 Service Pack 1, ReflectionPermission con el marcador ReflectionPermissionFlag.ReflectionEmit cuando se emiten ensamblados y métodos dinámicos. Este marcador se requiere en todas las versiones anteriores de .NET Framework.
Nota |
---|
El permiso ReflectionPermission con el marcador ReflectionPermissionFlag.ReflectionEmit está incluido de forma predeterminada en el conjunto de permisos con nombre FullTrust y LocalIntranet, pero no en el conjunto de permisos Internet.Por consiguiente, en versiones anteriores de .NET Framework, una biblioteca únicamente se puede utilizar con permisos de Internet si ejecuta un permiso Assert para ReflectionEmit.Estas bibliotecas requieren una revisión cuidadosa de la seguridad porque los errores de codificación pueden provocar vulnerabilidades de seguridad..NET Framework 2.0 SP1 permite emitir el código en escenarios de confianza parcial sin emitir ninguna petición de seguridad, porque la generación de código no es en sí una operación de privilegio.Es decir, el código generado no tiene más permisos que el ensamblado que lo emite.Esto permite que bibliotecas que emiten código sean transparentes en seguridad y quita la necesidad de validar ReflectionEmit, lo que simplifica la tarea de escribir una biblioteca segura. |
Además, .NET Framework 2.0 SP1 introduce el marcador ReflectionPermissionFlag.RestrictedMemberAccess para obtener acceso a los tipos y miembros no públicos de los métodos dinámicos de confianza parcial. Las versiones anteriores de .NET Framework requieren el marcador ReflectionPermissionFlag.MemberAccess para los métodos dinámicos que tienen acceso a tipos y miembros no públicos; éste es un permiso que nunca debería concederse al código de confianza parcial.
Finalmente, .NET Framework 2.0 SP1 introduce los métodos hospedados de forma anónima.
Obtener información de los tipos y miembros
A partir de .NET Framework 2.0, no se requieren permisos para obtener información sobre los tipos y miembros no públicos. La reflexión se utiliza a la hora de obtener la información necesaria para emitir métodos dinámicos. Por ejemplo, los objetos MethodInfo se utilizan para emitir llamadas a métodos. Las versiones anteriores de .NET Framework requieren el permiso ReflectionPermission con el marcador ReflectionPermissionFlag.TypeInformation. Para obtener más información, vea Consideraciones de seguridad sobre la reflexión.
Vea también
Conceptos
Consideraciones de seguridad sobre la reflexión