Cambios de seguridad en .NET Framework 4

Se han llevado a cabo dos cambios importantes en la seguridad de .NET Framework versión 4. Se ha eliminado la directiva de seguridad de ámbito de máquina, aunque el sistema de permisos permanece en vigor y la transparencia en seguridad se ha convertido en el mecanismo de exigencia predeterminado. (Para obtener más información, vea Código transparente en seguridad, nivel 2). Además, algunas operaciones de permisos que presentaban vulnerabilidades potenciales de seguridad ahora están obsoletas.

Nota importanteImportante

La seguridad de acceso del código (CAS) no se ha eliminado, la directiva de seguridad se ha eliminado de CAS, pero la evidencia y los permisos todavía están en vigor.Se han eliminado algunos permisos y la transparencia ha simplificado el cumplimiento de la seguridad.Para obtener una breve información general sobre los cambios, vea Resumen de los cambios en la seguridad de acceso del código.

Es necesario tener en cuenta los puntos principales siguientes:

  • La transparencia separa código que se ejecuta como parte de la aplicación de código que se ejecuta como parte de la infraestructura. Se introdujo en .NET Framework versión 2.0 y se ha mejorado para convertirse en el mecanismo de exigencia de seguridad de acceso del código. A diferencia de la directiva de seguridad, las reglas de transparencia de nivel 2 se exigen en tiempo de ejecución, no en el momento de carga del ensamblado. Estas reglas siempre están en vigor, incluso para los ensamblados que se ejecutan de forma predeterminada como de plena confianza. Sin embargo, la transparencia de nivel 2 no afecta al código de plena confianza que no está marcado, como las aplicaciones de escritorio. Los ensamblados (incluidos los ensamblados de escritorio) que se marcan con SecurityTransparentAttribute y que llaman a métodos marcados con SecurityCriticalAttribute reciben una MethodAccessException. Puede cambiar este comportamiento si aplica SecurityRulesAttribute y establece la propiedad SecurityRulesAttribute.RuleSet en Level1; sin embargo, debe hacerlo solo por compatibilidad con versiones anteriores. Debe marcar explícitamente una aplicación de escritorio como transparente en seguridad para poder aplicarle restricciones de transparencia.

  • El código que llama a las API de la directiva de seguridad recibe una NotSupportedException además de advertencias del compilador en tiempo de ejecución. La directiva puede rehabilitarse utilizando el elemento de configuración <NetFx40_LegacySecurityPolicy>. Cuando la directiva está habilitada, la transparencia en seguridad continúa en vigor. La directiva de seguridad se aplica en el momento de carga de ensamblado y no tiene ningún efecto en la transparencia, que es exigida por el runtime.

  • Los permisos de solicitud obsoletos (RequestMinimum, RequestOptional y RequestRefuse) reciben las advertencias del compilador y no funcionan en .NET Framework 4, pero no producen ninguna excepción. Las solicitudes Deny producen una NotSupportedException en tiempo de ejecución.

  • La acción de seguridad LinkDemand no está obsoleta, pero no se debería utilizar para comprobar los permisos. En su lugar, utilice SecurityCriticalAttribute para los tipos y métodos que requieren plena confianza o el método Demand para los tipos y métodos que requieren permisos individuales.

  • Si su aplicación se compila con Visual Studio 2010, puede ejecutarla sin estos cambios especificando una versión de .NET Framework de destino que sea anterior a .NET Framework 4 en la configuración de proyecto de Visual Studio. Sin embargo, no podrá utilizar nuevos tipos y miembros de .NET Framework 4. También puede especificar una versión anterior de .NET Framework utilizando el elemento <supportedRuntime> en el esquema de configuración de inicio de su archivo de configuración de la aplicación.

En las siguientes secciones se discuten éstos y otros cambios de .NET Framework 4: 

  • Simplificación de la directiva de seguridad

  • Nivel 2 de transparencia en seguridad

  • Solicitudes de permisos obsoletos

  • APTCA condicional

  • Objetos de evidencia

  • Colecciones de evidencia

Simplificación de la directiva de seguridad

A partir de .NET Framework 4, Common Language Runtime (CLR) comienza a dejar de proporcionar directivas de seguridad a los equipos. Históricamente, .NET Framework ha proporcionado la directiva de seguridad de acceso del código (CAS) como un mecanismo para controlar y configurar las capacidades de código administrado. Aunque la directiva de CAS es eficaz, puede ser complicada y restrictiva. Además, la directiva CAS no se aplica a las aplicaciones nativas, de modo que las garantías de seguridad se limitan. Los administradores del sistema deben buscar soluciones en el nivel del sistema operativo como Windows Software Restriction Policies (SRP) o AppLocker en Windows 7 y Windows Server 2008 R2 como reemplazo de la directiva de CAS. Las directivas SRP y AppLocker proporcionan mecanismos confiables simples que se aplican a código administrado y código nativo. Como soluciones de directiva de seguridad, SRP y AppLocker son más sencillas y proporcionan mejores garantías de seguridad que CAS.

En .NET Framework 4, la directiva de seguridad de nivel de equipo está desactivada de forma predeterminada. Las aplicaciones que no se hospedan (es decir, las aplicaciones que se ejecutan a través de Explorador de Windows o de un símbolo del sistema) ahora se ejecutan con plena confianza. Esto incluye todas las aplicaciones que residen en ubicaciones compartidas en la red local. Las aplicaciones hospedadas o en espacios aislados continúan ejecutándose con directivas de confianza que deciden sus hosts (por ejemplo, Internet Explorer, ClickOnce o ASP.NET). Las aplicaciones o controles que se ejecutan en espacio aislado se consideran de confianza parcial.

Para simplificar la directiva de seguridad, el modelo de la transparencia se ha aplicado a .NET Framework. Las aplicaciones y controles que se ejecutan en un host o espacio aislado con el conjunto de permisos limitado concedido por el espacio aislado se consideran transparentes. La transparencia significa que no tiene que preocuparse sobre cómo comprobar la directiva de CAS cuando ejecute aplicaciones de confianza parcial. Las aplicaciones transparentes simplemente se ejecutan usando su conjunto de permisos concedidos. Como programador, su única preocupación debería ser que sus aplicaciones tengan como destino el conjunto de permisos concedidos para su espacio aislado y que no llamen a código que requiera plena confianza (código crítico para la seguridad).

Nota importanteImportante

Como resultado de estos cambios en la directiva de seguridad, puede encontrarse con advertencias de compilación y excepciones en tiempo de ejecución si llama a tipos y miembros obsoletos de la directiva CAS de forma explícita o implícita (mediante otros tipos y miembros).Para obtener una lista de los tipos y miembros obsoletos y sus reemplazos, vea Compatibilidad con la directiva de seguridad de acceso del código y migración.

Para evitar las advertencias y los errores, use el elemento de configuración <NetFx40_LegacySecurityPolicy>en el esquema de configuración del runtime para optar por el comportamiento de la directiva CAS heredada.Sin embargo, especificar el uso de la directiva de seguridad heredada no incluye ninguna directiva CAS personalizada para esa versión a menos que se migre a .NET Framework 4.

También puede habilitar la directiva CAS heredada estableciendo la versión de .NET Framework de destino del proyecto de Visual Studio en una versión anterior a .NET Framework 4. Esto habilita la directiva CAS heredada e incluye cualquier directiva CAS personalizada que especificara para esa versión.Sin embargo, no podrá utilizar nuevos tipos y miembros de .NET Framework 4.También puede especificar una versión anterior de .NET Framework utilizando el elemento <supportedRuntime> en el esquema de configuración de inicio.

Volver al principio

Nivel 2 de transparencia en seguridad

La transparencia en seguridad se introdujo en .NET Framework versión 2.0, pero era muy limitada y se usó básicamente para mejorar la eficiencia de validación de código. En .NET Framework 4, la transparencia es un mecanismo de exigencia de seguridad que separa el código que se ejecuta como parte de la aplicación del código que se ejecuta como parte de la infraestructura. La transparencia levanta una barrera entre código que puede realizar acciones con privilegios (código crítico), como llamar a código nativo, y código que no puede realizar dichas acciones (código transparente). El código transparente puede ejecutar comandos dentro de los límites del conjunto de permisos en el que está funcionando, pero no puede ejecutar, llamar, derivar ni contener código crítico.

El objetivo principal de la exigencia de transparencia es proporcionar un mecanismo sencillo y eficaz para aislar grupos diferentes de código según los privilegios. En el modelo de espacio aislado, estos grupos de privilegios son de plena confianza (es decir, no restringido) o de confianza parcial (es decir, restringido al conjunto de permisos concedido al espacio aislado).

Las aplicaciones de escritorio se ejecutan con plena confianza; por tanto, el modelo de la transparencia no les afecta. Para obtener más información acerca de los cambios relacionados con la transparencia en seguridad, vea Código transparente en seguridad, nivel 2.

Volver al principio

Solicitudes de permisos obsoletos

La compatibilidad con runtime se ha quitado para exigir las solicitudes de permisos Deny, RequestMinimum, RequestOptional y RequestRefuse. En general, estas solicitudes no fueron bien comprendidas y no presentaron adecuadamente las posibles vulnerabilidades de seguridad si no se usaban correctamente:

  • Una acción Assert podía invalidarse con facilidad con una acción Deny. El código de un ensamblado podía ejecutar una acción Assert para un permiso si el permiso estaba en el conjunto de permisos concedidos al ensamblado. Assert impedía que Deny se viera en la pila, con lo que era ineficaz.

  • No se podía utilizar RequestMinimum eficazmente fuera del ámbito de aplicación. Si RequestMinimum aparecía en un archivo ejecutable (.exe) y no se satisfacía el conjunto de permisos concedidos, los usuarios finales del archivo recibían una excepción FileLoadException no controlada que no contenía ninguna información para corregir el problema. No se podía utilizar ningún grupo de solicitudes mínimas para las bibliotecas (archivos .dll), porque los tipos y miembros del ensamblado tienen, por lo general, requisitos de permisos diferentes.

  • RequestOptional era confusa y a menudo se utilizaba incorrectamente con resultados inesperados. Los desarrolladores de software podían omitir con facilidad los permisos de la lista sin comprender que al hacerlo implícitamente, se rechazaban los permisos omitidos.

  • RequestRefuse no proporcionaba un modelo eficaz de privilegio mínimo, porque exigía que se identificaran explícitamente los permisos que no se deseaban, en lugar de identificar los permisos que se necesitaban. Además, cuando aparecían nuevos permisos, no se incluían en la lista. Por otra parte, la negativa no tenía sentido para todos los permisos. Por ejemplo, se podría rechazar un valor para la propiedad UserQuota en IsolatedStoragePermission.

    Finalmente, especificando únicamente los permisos que no deseaba se creaba la posibilidad de que surgieran vulnerabilidades de seguridad al no identificar todos los permisos potencialmente dañinos.

  • RequestOptional y RequestRefuse permitían que los desarrolladores interrumpieran los dominios homogéneos mediante la creación de varios conjuntos de permisos dentro del dominio.

.NET Framework 4 quita la exigencia en tiempo de ejecución de estos valores de enumeración. Los ensamblados que contienen los atributos que utilizan estos valores SecurityAction continuarán cargándose; sin embargo, el CLR no rechazará cargar los ensamblados a los que se hace referencia ni modificará el conjunto de permisos concedidos basado en los conjuntos de permisos.

Volver al principio

APTCA condicional

El uso condicional del atributo AllowPartiallyTrustedCallersAttribute (APTCA) permite a los hosts identificar los ensamblados que desean exponer a los llamadores de confianza parcial cargados en el contexto del host. Esos ensamblados ya deben estar diseñados para la confianza parcial; es decir, deben tener el atributo APCTA (ser críticos para la seguridad y disponibles desde código transparente en el modelo de transparencia) o ser totalmente transparentes. Un nuevo constructor de la clase AllowPartiallyTrustedCallersAttribute permite al host especificar el nivel de visibilidad de un ensamblado APTCA mediante la enumeración PartialTrustVisibilityLevel en la llamada al constructor.

Volver al principio

Objetos de evidencia

Antes de .NET Framework 4, cualquier objeto se podía utilizar como un objeto de evidencia si el código de hospedaje deseaba aplicarlo como evidencia. Por ejemplo, algún código de .NET Framework reconocía los objetos System.Uri como evidencia. El runtime consideraba los objetos de evidencia como referencias System.Object y no les aplicaba ninguna seguridad de tipos.

Esto presentaba un problema porque .NET Framework imponía restricciones implícitas sobre los tipos que se podían utilizar como objetos de evidencia. Específicamente, cualquier objeto utilizado como evidencia tenía que ser serializable y no podía ser null. Si no se cumplían estos requisitos, el CLR producía una excepción cada vez que se llevaba a cabo una operación que requería una de estas suposiciones.

Para habilitar las restricciones en los tipos de objetos que se pueden utilizar como evidencia y proporcionar la capacidad de agregar nuevas características y requisitos a todos los objetos de evidencia, .NET Framework 4 presenta una nueva clase base System.Security.Policy.EvidenceBase, de la que deben derivar todos los objetos de evidencia. La clase EvidenceBase asegura, durante la creación de instancias, que el objeto de evidencia es serializable. Por otra parte, los nuevos requisitos de evidencia se podrán crear en el futuro agregando nuevas implementaciones predeterminadas a la clase base.

Compatibilidad con versiones anteriores

Todos los tipos utilizados por el CLR como objetos de evidencia se han actualizado en .NET Framework 4 para derivar de EvidenceBase. Sin embargo, los tipos de evidencia personalizados empleados por aplicaciones de terceros no se conocen y no pueden actualizarse. Por tanto, esos tipos de evidencia no se pueden usar con los nuevos miembros que esperan una evidencia derivada de EvidenceBase.

Volver al principio

Colecciones de evidencia

Antes de .NET Framework 4, el CLR generaba el conjunto completo de objetos de evidencia que se aplicaban a un ensamblado cuando este se cargaba. Estos objetos se almacenaban en una lista que los consumidores recorrían en iteración para buscar un objeto concreto. Por consiguiente, toda la evidencia estaba disponible, fuera o no utilizada. Para la mayoría de los objetos de evidencia, este comportamiento no era un problema; sin embargo, para los objetos de evidencia como System.Security.Policy.Publisher (que requiere la comprobación Authenticode), este comportamiento era ineficaz.

Para mejorar este comportamiento, la interacción con la colección de evidencia se ha rediseñado en .NET Framework 4. Una colección de evidencia se comporta ahora como un diccionario en lugar de como una lista. En lugar de recorrer en iteración la colección para ver si un objeto de evidencia necesario existe, los consumidores pueden solicitar un tipo específico de evidencia y la colección la devuelve si la encuentra. Por ejemplo, la llamada a StrongName name = evidence.GetHostEvidence<StrongName>(); devuelve un objeto StrongName si existe; de lo contrario, devuelve null.

Este modelo de diccionario retrasa la generación de objetos de evidencia hasta que se soliciten. En el ejemplo de evidencia Publisher, la sobrecarga de rendimiento de comprobar la firma Authenticode de un ensamblado se retrasa hasta que se necesita esa información. En el caso más común de aplicaciones de plena confianza donde no se necesita evidencia Publisher, se evita totalmente el proceso de comprobación.

Volver al principio

Vea también

Conceptos

Código transparente en seguridad

Código transparente en seguridad, nivel 2

Compatibilidad con la directiva de seguridad de acceso del código y migración