Los tipos APTCA se deberían extender en tipos base APTCA
Actualización: noviembre 2007
Nombre de tipo |
AptcaTypesShouldOnlyExtendAptcaBaseTypes |
Identificador de comprobación |
CA2117 |
Categoría |
Microsoft.Security |
Cambio problemático |
Sí |
Motivo
Un tipo público o protegido en un ensamblado con el atributo System.Security.AllowPartiallyTrustedCallersAttribute hereda de un tipo declarado en un ensamblado que no tiene el atributo.
Descripción de la regla
De forma predeterminada, Peticiones de herencia protege implícitamente los tipos públicos o protegidos de ensamblados con nombres seguros y de plena confianza. Los ensamblados con nombre seguro marcados con el atributo AllowPartiallyTrustedCallersAttribute (APTCA) no tienen esta protección. El atributo deshabilita la solicitud de herencia. Esto hace que los tipos expuestos declarados en el ensamblado los puedan heredar tipos que no son de plena confianza.
Si está presente el atributo APTCA en un ensamblado con plena confianza y un tipo del ensamblado se hereda de otro que permite llamadores parcialmente confiables, se puede producir un ataque en el sistema de seguridad. Si dos tipos T1 y T2 cumplen las condiciones siguientes, los llamadores malintencionados pueden hacer que el tipo T1 omita la solicitud implícita de vínculo de plena confianza que protege T2:
T1 es un tipo público declarado en un ensamblado de plena confianza que tiene el atributo APTCA.
T1 hereda de un tipo T2 fuera de su ensamblado.
El ensamblado de T2 no tiene el atributo APTCA y, por consiguiente, no lo deben heredar los tipos en ensamblados que no son de plena confianza.
Un tipo X de confianza parcial puede heredar de T1, que le da acceso a los miembros heredados declarados en T2. Puesto que T2 no tiene el atributo APTCA, su tipo derivado inmediato (T1) debe cumplir una solicitud de herencia de plena confianza; T1 es de plena confianza y, por tanto, supera esta comprobación. Existe un riesgo de seguridad porque X no participa en el cumplimiento de la solicitud de herencia que protege T2 de subclases que no son de plena confianza. Por esta razón, los tipos con el atributo APTCA no deben extender los que no lo tengan.
Otro problema de seguridad, y quizás uno más habitual, es que el tipo derivado (T1) puede, por un error del programador, exponer miembros protegidos desde el tipo que requiere plena confianza (T2). En este caso, los llamadores que no son de plena confianza obtienen acceso a la información que sólo debería estar disponible para los de plena confianza.
Cómo corregir infracciones
Si el tipo del que la infracción ha informado está en un ensamblado que no requiere el atributo APTCA, quítelo.
Si se requiere el atributo APTCA, agregue una solicitud de herencia de plena confianza para el tipo. De esta forma, los tipos que no son de confianza se protegen contra la herencia.
Es posible corregir una infracción agregando el atributo APTCA a los ensamblados de los tipos base de los que informó la infracción. No lleve a cabo esta acción sin revisar primero y a fondo la seguridad de todo el código de los ensamblados, así como todo el código que depende de ellos.
Cuándo suprimir advertencias
Para suprimir una advertencia de esta regla de forma segura, se debe asegura de que los miembros protegidos expuestos por el tipo no permiten, directa ni indirectamente, que los llamadores que no sean de confianza tengan acceso a información confidencial, operaciones ni recursos que se puedan usar de forma destructiva.
Ejemplo
El ejemplo siguiente utiliza dos ensamblados y una aplicación de prueba para mostrar la vulnerabilidad de seguridad detectada por esta regla. El primer ensamblado no tiene el atributo APTCA y los tipos de confianza parcial lo heredan (representados por T2 en la descripción anterior).
using System;
using System.Security;
using System.Security.Permissions;
using System.Reflection;
// This code is compiled into a strong-named assembly
// that requires full trust.
namespace AptcaTestLibrary
{
public class ClassRequiringFullTrustWhenInherited
{
// This field should be overridable by fully trusted derived types.
protected static string location = "shady glen";
// A trusted type can see the data, but cannot change it.
public virtual string TrustedLocation
{
get
{
return location;
}
}
}
}
El segundo ensamblado, representado por T1 en la descripción previa, es de plena confianza y permite llamadores de confianza parcial.
using System;
using System.Security;
using System.Security.Permissions;
using System.Reflection;
// This class is compiled into an assembly that executes with full
// trust and allows partially trusted callers.
// Violates rule: AptcaTypesShouldOnlyExtendAptcaBaseTypes.
namespace AptcaTestLibrary
{
public class InheritAClassRequiringFullTrust:
ClassRequiringFullTrustWhenInherited
{
private DateTime meetingDay = DateTime.Parse("February 22 2003");
public override string ToString()
{
// Another error:
// This method gives untrusted callers the value
// of TrustedLocation. This information should
// only be seen by trusted callers.
string s = String.Format(
"Meet at the {0} {1}!",
this.TrustedLocation, meetingDay.ToString());
return s;
}
}
}
El tipo de prueba, representado por X en la descripción anterior, está en un ensamblado de confianza parcial.
using System;
using AptcaTestLibrary;
// If this test application is run from the local machine,
// it gets full trust by default.
// Remove full trust.
[assembly: System.Security.Permissions.PermissionSetAttribute(
System.Security.Permissions.SecurityAction.RequestRefuse, Name = "FullTrust")]
namespace TestSecLibrary
{
class InheritFromAFullTrustDecendent : ClassRequiringFullTrust
{
public InheritFromAFullTrustDecendent()
{
// This constructor maliciously overwrites the protected
// static member in the fully trusted class.
// Trusted types will now get the wrong information from
// the TrustedLocation property.
InheritFromAFullTrustDecendent.location = "sunny meadow";
}
public override string ToString()
{
return InheritFromAFullTrustDecendent.location;
}
}
class TestApctaInheritRule
{
public static void Main()
{
ClassRequiringFullTrust iclass =
new ClassRequiringFullTrust();
Console.WriteLine(iclass.ToString());
// You cannot create a type that inherits from the full trust type
// directly, but you can create a type that inherits from
// the APTCA type which in turn inherits from the full trust type.
InheritFromAFullTrustDecendent inherit =
new InheritFromAFullTrustDecendent();
//Show the inherited protected member has changed.
Console.WriteLine("From Test: {0}", inherit.ToString());
// Trusted types now get the wrong information from
// the TrustedLocation property.
Console.WriteLine(iclass.ToString());
}
}
}
Este ejemplo produce el siguiente resultado.
Meet at the shady glen 2/22/2003 12:00:00 AM!
From Test: sunny meadow
Meet at the sunny meadow 2/22/2003 12:00:00 AM!
Reglas relacionadas
Los métodos APTCA sólo deberían llamar a métodos APTCA
Vea también
Conceptos
Ensamblados de .NET Framework marcados con AllowPartiallyTrustedCallersAttribute
Utilizar bibliotecas de código que no es de plena confianza