Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Migración de un ensamblado APTCA a .NET Framework 4
En Microsoft .NET Framework 4, el modelo de seguridad de Common Language Runtime (CLR) ha experimentado algunos cambios considerables. Uno de estos cambios, la adopción de la transparencia Level2 (que se asemeja al modelo de seguridad de Silverlight), probablemente impacte a los autores de las bibliotecas AllowPartiallyTrustedCallers (APTCA).
El motivo del impacto es que los trabajos subyacentes de APTCA han cambiado en CLR v4. El atributo APTCA retiene la capacidad de poner a disposición de autores de llamada de confianza parcial una biblioteca de plena confianza, pero los detalles de cómo sucede son diferentes y, como resultado, probablemente sean necesarias algunas modificaciones al código de biblioteca APTCA.
Nota: las referencias a v2 en este artículo tienen relación con CLR v2, que incluye todo desde las versiones 2.0 de .NET Framework hasta 3.5 SP1.
APTCA antes de V4
Antes de v4, todos los ensamblados firmados estaban protegidos contra autores de llamada de confianza parcial por peticiones de vínculo implícitas para plena confianza en todos los puntos de entrada. Esto significaba que cuando algún código de confianza parcial intentaba tener acceso a un ensamblado con nombre se producía error con una excepción de seguridad. Esto impedía que confianza parcial llamara a código de plena confianza (potencialmente peligroso) de forma malintencionada.
Agregar el atributo AllowPartiallyTrustedCallers a una biblioteca de plena confianza firmada lo pone a disposición de confianza parcial al eliminar estas peticiones de vínculo implícitas. En consecuencia, las bibliotecas APTCA permitían acceso controlado de código de confianza parcial a operaciones privilegiadas a través de métodos expuestos por APTCA. Era responsabilidad de los autores de APTCA asegurarse de que sólo las operaciones seguras estuvieran expuestas a confianza parcial de esta manera y que cualquier operación potencialmente peligrosa estuviera protegida con peticiones de vínculo implícitas o con peticiones plenas.
APTCA en V4
El atributo AllowPartiallyTrustedCallers ha cambiado. En v4, éste ya no tiene ninguna relación con las peticiones de vínculo. De hecho, ya no existe la petición de vínculo implícita que estaba presente en las bibliotecas firmadas. En su lugar, todos los ensamblados de plena confianza en v4 son, de forma predeterminada, SecurityCritical. Por otra parte, todos los ensamblados de plena confianza automáticamente son SecurityTransparent en v4. Como se explica en la información general de transparencias de la siguiente sección, el código SecurityCritical no se puede llamar desde el código SecurityTransparent.
De ese modo, el nuevo sistema de transparencias de v4 proporciona la misma protección de código de plena confianza que las antiguas peticiones de vínculo; debido a los niveles automáticos de transparencia SecurityCritical y SecurityTransparent, el código de confianza parcial no se puede llamar de forma predetermina desde bibliotecas de plena confianza.
Como puede haberlo deducido, el cambio de v4 a AllowPartiallyTrustedCallers está relacionado con esto. En v4, el efecto de APTCA es eliminar el comportamiento automático SecurityCritical del ensamblado al cual se aplica. El ensamblado después se define de forma predeterminada en SecurityTransparent, pero permite que el autor del ensamblado APTCA aplique atributos SecurityCritical y SecuritySafeCritical más pormenorizados a tipos y métodos específicos, según sea necesario.
Curso intensivo sobre transparencias
El efecto de los atributos de transparencia como SecurityTransparent y SecurityCritical será conocido para los lectores familiarizados con el modelo de seguridad de Silverlight, porque el nuevo modelo de transparencias de v4 es bastante similar.
Analicemos los tres atributos de transparencia principales: SecurityTransparent, SecuritySafeCritical y SecurityCritical.
SecurityTransparent El código marcado como SecurityTransparent es seguro desde una perspectiva de seguridad. No se puede completar ninguna operación peligrosa, tal como imponer un permiso, ejecutar código no comprobable o llamar a código nativo. No se puede llamar directamente al código SecurityCritical.
- Como se indicó, todo código de confianza parcial es forzado a ser SecurityTransparent por motivos de seguridad. También es la transparencia predeterminada de las bibliotecas APTCA.
SecurityCritical El código SecurityCritical, en cambio, puede realizar todas las operaciones que desee. Puede imponer, llamar a código nativo y más. Puede llamar a otros métodos, sin importar las marcas de transparencia.
- Sólo un código de plena confianza puede ser SecurityCritical. Y, en realidad, se supone que un código de plena confianza (que no sea APTCA) es SecurityCritical, de forma predeterminada, para protegerlo contra autores de llamada transparentes de confianza parcial.
SecuritySafeCritical El código SecuritySafeCritical actúa como un puente, lo que permite que el código transparente llame a métodos críticos. El código SecuritySafeCritical cuenta con los mismos derechos que el código SecurityCritical, pero se puede llamar desde el código SecurityTransparent. Por lo tanto, es extremadamente importante que el código SecuritySafeCritical exponga los métodos subyacentes SecurityCritical sólo de una forma segura (para evitar que algún código de confianza parcial malintencionado intente vulnerar la seguridad de los métodos a través del nivel SecuritySafeCritical).
- Al igual que el código SecurityCritical, el código SecuritySafeCritical debe ser de plena confianza.
En la figura 1 se ilustran las interacciones de los códigos SecurityTransparent, SecuritySafeCritical y SecurityCritical.
Figura 1 Interacciones de los códigos SecurityTransparent, SecuritySafeCritical y SecurityCritical
Observe que, además de las transiciones que se muestran en el diagrama, todos los niveles de transparencia pueden tener acceso a ellos y a cualquier código menos crítico (por ejemplo, el código SecuritySafeCritical puede tener acceso al código SecurityTransparent). Puesto que el atributo AllowPartiallyTrustedCallers hace que, de forma predeterminada, el ensamblado completo sea SecurityTransparent, el autor del ensamblado debe marcar específicamente los métodos que necesitan realizar operaciones privilegiadas como SecurityCritical o SecuritySafeCritical. Sin esa marca, el autor de APTCA observará que su código presentará error con MethodAccessExceptions, TypeAccessExceptions y otros errores que indican que la biblioteca APTCA intenta llamar a API peligrosas desde el código SecurityTransparent.
Esta es sólo una breve introducción al modelo; podrá encontrar un análisis más completo en la documentación de MSDN en un artículo anterior de Todo sobre CLR de Andrew Dai, que se encuentra disponible en msdn.microsoft.com/magazine/ee677170.aspx.
Migración desde V2 a V4: qué atributos aplicar
La mayor parte del trabajo necesario para migrar un ensamblado APTCA v2 a v4 implica la identificación y la aplicación de los atributos de transparencia correctos a los métodos que los necesitan. A continuación, se señalan las instrucciones que indican cuándo es apropiado cada uno de los atributos.
SecurityTransparent Un código que no realiza ninguna operación compatible con seguridad debe ser SecurityTransparent.
A diferencia de la otra configuración de transparencia, el comportamiento de SecurityTransparent es el valor predeterminado en un ensamblado APTCA y, por lo tanto, no es necesario marcarlo explícitamente. Un código se considera transparente ante la ausencia de otros atributos.
Una ventaja de un código transparente es que es seguro (porque las operaciones peligrosas están deshabilitadas) y, como resultado, no necesita una revisión de seguridad completa como el código SecurityCritical o, específicamente, el código SecuritySafeCritical. Se recomienda que en lo posible el código sea SecurityTransparent.
Los siguientes aspectos están deshabilitados en el código SecurityTransparent:
- Llamar a los métodos SecurityCritical.
- Imponer un permiso o un conjunto de permisos.
- Código no comprobable.
- Llamar a código no administrado.
- Invalidar los métodos virtuales SecurityCritical.
- Implementar las interfaces SecurityCritical.
- Derivar cualquier tipo que no sea SecurityTransparent.
SecuritySafeCritical El código, que se puede llamar desde confianza parcial pero que necesita poder llamar a API potencialmente peligrosas, se debe marcar como SecuritySafeCritical. Con frecuencia, los métodos que soliciten permisos estarán dentro de esta categoría porque representan un límite protegido entre código de confianza parcial y operaciones privilegiadas.
Puesto que el código SecuritySafeCritical permite que los autores de llamada de confianza parcial tengan acceso indirecto a API peligrosas, es un atributo muy poderoso y se debe aplicar con cuidado y moderación. Es importante que el código SecuritySafeCritical exponga la funcionalidad SecurityCritical a sus autores de llamada sólo de formas específicas y seguras. Generalmente, es buena idea que el código SecuritySafeCritical contenga peticiones para asegurarse de que los autores de llamada puedan tener acceso a recursos específicos que el código SecuritySafeCritical vaya a utilizar. También es importante que el código SecuritySafeCritical valide las entradas y las salidas (para asegurarse de que no se transmitan valores no válidos y que cualquier información devuelta sea segura de proporcionar a confianza parcial).
Debido a los posibles riesgos de seguridad, se recomienda que el código SecuritySafeCritical se mantenga en un mínimo.
SecurityCritical El código, que no sea seguro exponer a autores de llamada de confianza parcial, se debe marcar como SecurityCritical. Es probable que los métodos que antes estaban protegidos por una petición de vínculo necesiten este atributo.
El código SecurityCritical es menos peligroso que el código SecuritySafeCritical porque los autores de llamada transparentes (de confianza parcial) no pueden llamarlo directamente. Sin embargo, el código puede realizar varias operaciones de alta seguridad; por lo tanto, con el propósito de mantener en un mínimo la necesidad de revisiones de seguridad, también es buena idea mantener en un mínimo el código SecurityCritical.
Una buena orientación general es que cualquier código que pueda ser SecurityTransparent debe serlo. Otro código debe ser SecurityCritical, salvo que se espere específicamente que el código transparente tenga acceso al código SecurityCritical a través de éste, en cuyo caso, el código SecuritySafeCritical es apropiado.
Uso de SecAnnotate.exe
Con el propósito de ayudar en la correcta aplicación de los atributos de transparencia, hay disponible una nueva herramienta de .NET Framework SDK: Security Annotator (SecAnnotate.exe). Esta herramienta consume un binario (o una colección de binarios) de usuario y proporciona orientación sobre dónde se deben aplicar los atributos de transparencia. Puede ser muy útil al migrar una biblioteca APTCA a v4.
SecAnnotate realiza varias pasadas a través del binario de destino, en busca de métodos que, de acuerdo con las reglas de CLR, sea necesario marcar con un atributo de transparencia. En pasadas posteriores, la herramienta busca atributos que sean necesarios debido a las modificaciones que se sugirieron en las pasadas anteriores. Por ejemplo, tenga en cuenta este fragmento corto de código (que se supone proviene de un ensamblado APTCA):
static void Method1()
{
Console.WriteLine("In method 1!");
Method2();
}
static void Method2()
{
PermissionSet ft = new PermissionSet(PermissionState.Unrestricted);
ft.Assert();
DangerousAPI();
PermissionSet.RevertAssert();
}
SecAnnotate.exe inmediatamente observaría que Method2 no puede ser transparente porque impone algunos permisos. Después de la primera pasada, la herramienta sabría que Method2 debe ser SecurityCritical o SecuritySafeCritical (en que se prefiere SecurityCritical, salvo que un código transparente necesite tener acceso específicamente a este método).
En la primera pasada a través del binario, Method1 no sería interesante para la herramienta. Sin embargo, en la segunda pasada, observaría que Method1 llama a Method2, que, durante la primera pasada, SecAnnotate sugirió que se transformara en SecurityCritical. Debido a esto, también sería necesario que Method1 fuera SecurityCritical (o, a discreción del autor, SecuritySafeCritical). Después de dos pasadas, se proporcionaría la orientación de marcar ambos métodos como SecurityCritical.
Descripción de la salida SecAnnotate.exe
La salida de Security Annotator es un archivo XML que contiene los problemas que ha identificado y las correcciones recomendadas. En algunas ocasiones, Security Annotator revierte una recomendación anterior después de pasadas posteriores. En esos casos, ambas recomendaciones aparecen en el archivo XML. Será necesario que observe el número de pasada en estos casos para entender qué recomendación es más reciente y, por lo tanto, correcta.
Por ejemplo, tenga en cuenta la salida de Security Annotator en la figura 2. Observe que había dos elementos bajo la etiqueta de anotaciones para el método Logging.MethodA: una etiqueta SecuritySafeCritical y una etiqueta SecurityCritical. Esto significa que SecAnnotate recomendaba los atributos SecurityCritical y SecuritySafeCritical para este método durante su análisis.
Figura 2 Salida de Security Annotator
<requiredAnnotations>
<assembly name="Logging">
<type name="Logging">
<method name="MethodA()">
<annotations>
<safeCritical>
<rule name="MethodsMustOverrideWithConsistentTransparency">
<reason pass="2" sourceFile="d:\repro\aptca\logging.cs" sourceLine="67">Critical method Logging.MethodA()’ is overriding transparent or safe critical method ‘Logging.MethodA()’ in violation of method override rules. Logging.MethodA()’ must become transparent or safe-critical in order to override a transparent or safe-critical virtual method or implement a transparent or safe-critical interface method.</reason>
</rule>
</safeCritical>
<critical>
<rule name="TransparentMethodsMustNotSatisfyLinkDemands">
<reason pass="1" sourceFile="d:\repro\aptca\logging.cs" sourceLine="68">Security transparent method Logging.MethodA()’ satisfies a LinkDemand for ‘FileIOPermissionAttribute’ on method ‘Logging.set_LogLocation(System.String)’. Logging.MethodA()’ should become critical or safe-critical in order to call ‘Logging.set_LogLocation(System.String)’.</reason>
</rule>
</critical>
</annotations>
</method>
</type>
</assembly>
</requiredAnnotations>
La explicación del elemento SecurityCritical indica que debido a que este método llama a algo protegido con una petición de vínculo, debe ser SecurityCritical o SecuritySafeCritical. SecAnnotate.exe está definido de forma predeterminada para recomendar SecurityCritical, porque es más seguro. Observe que el atributo de pasada tiene un valor de 1 aquí, lo que significa que esta sugerencia se originó en la primera pasada de SecAnnotate.exe a través del código.
La siguiente recomendación, para SecuritySafeCritical, observa que MethodA invalida un método base transparente y, por lo tanto, debe ser SecurityTransparent o SecuritySafeCritical (debe tener la misma accesibilidad que el método base). SecAnnotate.exe, al poner esta información junto con la recomendación anterior, sugiere que MethodA debe ser SecuritySafeCritical.
Observe que pass=“2” significa que esta recomendación provino durante la segunda pasada de SecAnnotate.exe a través del código. La causa de esto es que durante la primera pasada, la herramienta no sabía que MethodA podía no ser transparente, de modo que no tenía conocimiento de este requisito SecuritySafeCritical.
Puesto que la recomendación de SecuritySafeCritical se realizó durante la segunda pasada (más reciente), en este caso es la anotación correcta.
Procedimientos recomendados de SecAnnotate.exe
En aquellos casos en que tanto SecurityCritical como SecuritySafeCritical serían marcas correctas, Security Annotator primero prefiere cualquier atributo ya presente en el código y después SecurityCritical, porque es menos riesgoso. Desafortunadamente, con frecuencia esto origina un código que es seguro pero inutilizable en un espacio aislado, porque todos los puntos de entrada están bloqueados para los autores de llamada de confianza parcial.
Recuerde que SecuritySafeCritical es apropiado en las API que están diseñadas para llamarse directamente desde código transparente o de confianza parcial y cuya seguridad se ha revisado teniendo esto en cuenta. Puesto que Security Annotator no puede saber qué API están diseñadas para ser llamadas desde confianza parcial o son seguras para ser llamadas de esa forma, marcará muy poco como SecuritySafeCritical. El autor de la biblioteca debe aplicar de forma manual el atributo SecuritySafeCritical a algunos métodos, incluso cuando utilice Security Annotator.
Puesto que una sola acción prohibida en código transparente puede “formar una telaraña” en varias marcas SecurityCritical en las pasadas sucesivas de Security Annotator sin una selección de ubicación estratégica del atributo SecuritySafeCritical, es una práctica recomendada usar SecAnnotate.exe con el modificador de la línea de comandos /p. El modificador /p:x (donde x es un número) indica a Security Annotator que ejecute sólo x pasadas, en lugar de ejecutarse hasta que no sean necesarios más cambios. La siguiente es una buena forma de utilizar Security Annotator:
- Ejecute SecAnnotate.exe /p:1 /d:<Path en los ensamblados a los que se hace referencia> <FileName.dll>
a. Esto agrega atributos de transparencia cuando sea necesario, pero sólo con una sola pasada. Detenerse en este punto permite que el autor compruebe manualmente los atributos.
b. De forma predeterminada, SecAnnotate.exe busca sólo el GAC para las dependencias del ensamblado que está anotando. Otros ensamblados deben tener especificadas sus rutas de acceso con el modificador /d. - Actualice los archivos de origen de la biblioteca con los atributos sugeridos. Sin embargo, considere casos con varios atributos posibles y decida cuál es el correcto. En algunos casos, SecuritySafeCritical será el atributo correcto, a pesar de que SecAnnotate favorece SecurityCritical.
- Vuelva a crear los ensamblados y repita el paso 1 sin /p:1. Puede volver a ejecutar el programa usando /p:1 de forma repetida, pero no es necesario; los atributos SecuritySafeCritical necesarios ya están presentes después de la primera iteración del paso 2.
Este proceso iterativo con interacción manual del desarrollador dará como resultado un ensamblado anotado correctamente que maximiza el código transparente.
Identificación y revisión de las API de SecuritySafeCritical
Como se indicó anteriormente, es común que SecAnnotate.exe recomiende que una API sea SecurityCritical o SecuritySafeCritical. El diferenciador clave es si la API se puede llamar de forma segura desde confianza parcial. Si la API realiza toda la validación necesaria para asegurarse de que las API críticas o nativas subyacentes se llamarán de forma segura (por ejemplo, a través de peticiones o validación de entrada y salida), puede ser SecuritySafeCritical, que algunas veces es recomendable porque permite que los autores de llamada de la API sean transparentes. Si, por otra parte, existe alguna forma en que el código malintencionado pueda tener acceso a recursos protegidos a través de la API, esta última sigue siendo SecurityCritical.
Es importante que todo el código SecuritySafeCritical se revise cuidadosamente para comprobar cuál es el impacto a nivel de seguridad de la exposición a confianza parcial. Aunque los códigos SecuritySafeCritical y SecurityCritical se deben minimizar, si existe alguna duda en cuanto a qué atributo es correcto, SecurityCritical es la opción más segura.
Aplicación de atributos de transparencia
Aplicar atributos de transparencia es tan simple como aplicar cualquier otro atributo .NET en código. La documentación respecto al uso de los atributos se encuentra disponible en la documentación de MSDN para los siguientes tipos:
- SecurityTransparentAttribute
Observe que este atributo sólo se puede aplicar en el nivel de ensamblado. Su significado, en ese caso, es que todos los tipos y los métodos en el ensamblado son transparentes. No es necesario en el nivel de tipo o método porque es la configuración de transparencia predeterminada en los ensamblados APTCA. - SecuritySafeCriticalAttribute
- SecurityCriticalAttribute
En C#, la aplicación de los atributos es similar lo siguiente:
[SecurityCritical]
public static void Method1()
{ /* Do something potentially dangerous*/ }
[SecuritySafeCritical]
public static void Method2()
{ /* Do something potentially dangerous in a safe way that can be called from partial trust */ }
Level1 y Level2
Una nota final en cuanto a la transparencia y a APTCA es que es posible, mediante el uso de un atributo de nivel de ensamblado, usar el comportamiento de APTCA v2 anterior en lugar del comportamiento de APTCA v4 actual. Esto no se recomienda porque el nuevo modelo es más seguro, más fácil de auditar y común entre Silverlight y CLR de escritorio. Sin embargo, algunas veces se necesita compatibilidad a corto plazo hasta que pueda realizar la migración. En estos casos, el atributo SecurityRules se puede usar para forzar que un ensamblado utilice las reglas de v2 anterior.
El atributo SecurityRules toma un parámetro del tipo de enumeración SecurityRuleSet. SecurityRuleSet.Level1 especifica compatibilidad. SecurityRuleSet.Level2 especifica el nuevo modelo, pero un atributo Level2 no es necesario porque es el valor predeterminado. Sin embargo, puede ser útil para indicar explícitamente qué conjunto de reglas de transparencia se encuentra en uso y para protegerse contra futuros cambios en relación con qué conjunto de reglas es el valor predeterminado de .NET Framework.
En C#, la aplicación de este atributo es similar a lo siguiente:
[assembly:SecurityRules(SecurityRuleSet.Level1)]
Riesgos comunes
A continuación, se indican algunas “trampas” comunes ante las cuales los autores de la biblioteca APTCA deben ser cautelosos cuando realicen la migración de v2 a v4:
- SecAnnotate.exe recomendará que LinkDemands se convierta en atributos SecurityCritical (que son muy similares a LinkDemands para FullTrust). Sin embargo, si un tipo (en lugar de un método) estaba protegido con LinkDemand, esto no es lo mismo que aplicar SecurityCritical a un tipo en v4. Es mejor aplicar SecurityCritical a todos los miembros del tipo, ya que esto actuará más como LinkDemand de nivel de tipo de v2.
- Tenga en cuenta que es posible que algunos LinkDemands de permiso bajo, que algún código de confianza parcial espera poder satisfacer, no se puedan traducir mejor en SecurityCritical. Si LinkDemand es para permiso bajo (por ejemplo, permiso de lectura en una ruta de acceso segura específica), es mejor eliminar LinkDemand y reemplazarlo por una petición plena del mismo permiso. Esto permite que un código de confianza parcial aún pueda llamar a la API (pero la petición se asegurará de que sólo un código de confianza parcial con permisos de un nivel suficientemente alto pueda realizar la llamada).
- En general, los atributos de transparencia de nivel de tipo también se aplican a los miembros del tipo que modifican. Y el atributo exterior triunfa sobre los otros. De ese modo, aplicar [SecurityCritical] a un método es inútil, por ejemplo, si el tipo en que se encuentra ha aplicado [SecuritySafeCritical] a éste. Normalmente, [SecuritySafeCritical] no es un atributo útil en el nivel de tipo. Es bastante probable que alguien ingrese en el futuro un nuevo miembro al tipo y no se dé cuenta de que es SecuritySafeCritical (debido al atributo de nivel de tipo), lo que potencialmente origina una vulnerabilidad de seguridad.
Aunque los atributos de nivel de tipo se aplican a nuevos miembros de entrada de los tipos que modifican, no se aplican a los miembros invalidados. Si utiliza atributos de transparencia de nivel de tipo, también asegúrese de agregar atributos a los miembros invalidados específicamente, si es necesario.
Ejemplo de migración
La figura 3 es una biblioteca de registro simple (e incompleta) escrita en v2.
Figura 3 Biblioteca APTCA v2
using System;
using System.IO;
using System.Security;
using System.Security.Permissions;
// This assembly is meant to be representative of a simple v2 APTCA assembly
// It has some dangerous code protected with demands/link demands
// It exposes some dangerous code in a controlled way with an assert
[assembly: AllowPartiallyTrustedCallers]
public class Logging
{
private string logLocation = @"C:\temp\firstfoo.txt";
public virtual string Usage()
{
return "This is a helpful string";
}
public virtual string LogLocation
{
get
{
return logLocation;
}
[FileIOPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
set
{
logLocation = value;
}
}
public virtual void SetLogLocation(int index)
{
switch (index)
{
case 1:
LogLocation = @"C:\temp\foo.txt";
break;
case 2:
LogLocation = @"D:\temp\foo.txt";
break;
case 3:
LogLocation = @"D:\repro\temp\foo.txt";
break;
default:
break;
}
}
public virtual void DeleteLog()
{
FileIOPermission fp = new FileIOPermission(FileIOPermissionAccess.AllAccess, LogLocation);
fp.Assert();
if (File.Exists(LogLocation)) { File.Delete(LogLocation); }
SecurityPermission.RevertAll();
}
// TODO : Put other APIs (creating log, writing to log, etc) here
}
public class OtherLogging : Logging
{
public override string Usage()
{
LogLocation = null;
return "This is a different useful string";
}
// TODO : Put other APIs (creating log, writing to log, etc) here
}
La misma biblioteca también se muestra en la figura 4, que se migró a v4 con comentarios (en cursiva) que explican los cambios.
Figura 4 Biblioteca APTCA v4
using System;
using System.IO;
using System.Security;
using System.Security.Permissions;
// This assembly is meant to be representative of a simple v2 APTCA assembly
// It has some dangerous code protected with demands/link demands
// It exposes some dangerous code in a controlled way with an assert
[assembly: AllowPartiallyTrustedCallers]
public class Logging
{
private string logLocation = @"C:\temp\firstfoo.txt";
// This API can be transparent because it does nothing dangerous.
// Transparent APIs need no attributes because it is the default behavior of a v4
// APTCA assembly
public virtual string Usage()
{
return "This is a helpful string";
}
// Note that transparency attributes do not go directly on properties.
// Instead, they go on the getters and setters (even if the getter and setter
// get the same attributes)
public virtual string LogLocation
{
get
{
return logLocation;
}
// This API is made critical because it sets sensitive data (the path to write to)
// which partial trust code should not be able to do.
[SecurityCritical]
// The previous LinkDemand is removed as the SecurityCritical attribute replaces it
//[FileIOPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
set
{
logLocation = value;
}
}
// This API accesses a critical member (LogLocation) and, therefore, cannot be transparent
// However, the access is done in a limited, safe way and we expect transparent code
// should be able to call this API. Therefore, it is SecuritySafeCritical
[SecuritySafeCritical]
public virtual void SetLogLocation(int index)
{
switch (index)
{
case 1:
LogLocation = @"C:\temp\foo.txt";
break;
case 2:
LogLocation = @"D:\temp\foo.txt";
break;
case 3:
LogLocation = @"D:\repro\temp\foo.txt";
break;
default:
break;
}
}
// This API is potentially dangerous; it asserts which means it can’t be transparent
// Because setting LogLocation is protected, however, partial trust code can safely
// call this API. In fact, it is intended that it is safe for partial trust code
// to call this method. Therefore, it is SecuritySafeCritical
[SecuritySafeCritical]
public virtual void DeleteLog()
{
FileIOPermission fp = new FileIOPermission(FileIOPermissionAccess.AllAccess, LogLocation);
fp.Assert();
if (File.Exists(LogLocation)) { File.Delete(LogLocation); }
SecurityPermission.RevertAll();
}
// TODO : Put other APIs (creating log, writing to log, etc) here
}
public class OtherLogging : Logging
{
// The logic for attributing this method is complicated and it is an example of when
// SecAnnotate.exe can be very helpful. This API cannot be transparent because it
// calls a critical member (LogLocation). However, because it overrides a transparent
// method (Usage) it cannot be critical. Therefore, the only possible annotation here
// is SecuritySafeCritical and it is the author’s responsibility to make sure that
// a malicious caller cannot abuse that access.
[SecuritySafeCritical]
public override string Usage()
{
LogLocation = null;
return "This is a different useful string";
}
// TODO : Put other APIs (creating log, writing to log, etc) here
}
Sincronización de los sistemas de seguridad de CLR y de Silverlight CoreCLR
Aunque la combinación de APTCA y transparencia en v4 puede parecer compleja, finalmente suministra una protección sencilla y eficaz para los recursos de sistemas confidenciales contra autores de llamada de confianza parcial. Además, el cambio alinea los sistemas de seguridad de CLR de escritorio y de Silverlight CoreCLR.
Las herramientas SDK, tales como SecAnnotate.exe y las reglas FxCop (que pueden validar la transparencia), permiten que la migración sea más fácil. Los ensamblados APTCA v4 son más fáciles de auditar: un examen detenido de las API de SecuritySafeCritical (y las llamadas SecurityCritical que realizan) es todo lo se necesita para tener confianza de que el ensamblado es seguro.
Puesto que un código transparente con frecuencia conforma entre un 80 por ciento y un 90 por ciento, o incluso más, de un ensamblado, esto es un gran alivio de carga de auditoría. Los lectores interesados en investigar más sobre transparencia pueden encontrar explicaciones más completas en la documentación de MSDN.
Mike Rousosse ha desempeñado como ingeniero de diseño de software de prueba en el equipo CLR de Microsoft desde 2005. Su trabajo consiste principalmente en asegurar la calidad del diseño y la implementación de los sistemas de seguridad de CLR.
Gracias a los siguientes expertos técnicos por su ayuda en la revisión de este artículo:Andrew Dai, Cristian Eigel y Shawn Farkas