Seguridad de confianza parcial de WPF
En general, las aplicaciones de Internet deben tener restringido el acceso directo a los recursos del sistema críticos, a fin de evitar los daños malintencionados. De manera predeterminada, HTML y los lenguajes de script de cliente no pueden tener acceso a los recursos del sistema críticos. Dado que las aplicaciones Windows Presentation Foundation (WPF) hospedadas por el explorador se pueden iniciar desde el explorador, deben cumplir un conjunto de restricciones similar. Para exigir estas restricciones, WPF se basa en Code Access Security (CAS) y ClickOnce (consulte Estrategia de seguridad de WPF: Seguridad de plataforma). De manera predeterminada, las aplicaciones hospedadas por el explorador solicitan el conjunto de permisos Zona de Internet de CAS, con independencia de si se inician desde Internet, desde la intranet local o desde el equipo local. Se dice que las aplicaciones que se ejecutan con menos permisos que el conjunto completo de permisos se están ejecutando con confianza parcial.
WPF proporciona gran variedad de características de compatibilidad para asegurarse de que se pueda utilizar tanta funcionalidad como sea posible sin riesgo alguno en confianza parcial y, junto con CAS, proporciona la compatibilidad adicional para la programación de confianza parcial.
Este tema contiene las siguientes secciones:
Compatibilidad con la confianza parcial de las características de WPF
Programación de la confianza parcial
Administrar permisos
Compatibilidad con la confianza parcial de las características de WPF
En la tabla siguiente se muestra una lista de las características generales de Windows Presentation Foundation (WPF) que resulta seguro utilizar dentro de los límites del conjunto de permisos Zona de Internet.
Tabla 1: Características de WPF seguras con confianza parcial
Área de la característica |
Característica |
---|---|
General |
Explorador (Ventana) Acceso al sitio de origen Almacenamiento aislado (límite de 512 KB) Proveedores de automatización de la IU Comandos Editores de métodos de entrada (IME) Lápiz óptico de Tablet PC y entradas de lápiz Métodos de arrastrar y colocar simulados mediante eventos Capture y Move del mouse. OpenFileDialog Deserialización XAML (mediante XamlReader.Load) |
Integración en web |
Cuadro de diálogo de descarga del explorador Navegación de nivel superior iniciada por el usuario mailto:links Parámetros de identificador uniforme de recursos HTTPWebRequest Contenido WPF hospedado en IFRAME Hospedar páginas HTML del mismo sitio mediante Frame Hospedar páginas HTML del mismo sitio mediante WebBrowser Servicios Web (ASMX) Servicios Web (mediante Windows Communication Foundation) Scripting Modelo de objetos de documento |
Elementos visuales |
2D y 3D Animación Multimedia (sitio de origen y entre dominios) Imágenes/audio/vídeo |
Lectura |
Documentos dinámicos Documentos XPS Fuentes incrustadas y del sistema Fuentes CFF y TrueType |
Edición |
Revisión ortográfica RichTextBox Texto simple y compatibilidad de portapapeles de entradas de lápiz Acción de pegar iniciada por el usuario Copiar contenido seleccionado |
Controles |
Controles generales |
En esta tabla se muestran las características de WPF de alto nivel. Para obtener más información detallada, en Windows Software Development Kit (SDK) se documentan los permisos que necesita cada miembro en WPF. Asimismo, las características siguientes ofrecen información más detallada relativa a la ejecución de la confianza parcial, incluidas algunas consideraciones especiales.
XAML (consulte Información general sobre XAML (WPF)).
Menús emergentes (consulte System.Windows.Controls.Primitives.Popup).
Arrastrar y colocar (consulte Información general sobre la función de arrastrar y colocar).
Portapapeles (consulte System.Windows.Clipboard).
Imágenes (consulte System.Windows.Controls.Image).
Serialización (consulte XamlReader.Load, XamlWriter.Save).
Cuadro de diálogo de apertura de archivos (consulte Microsoft.Win32.OpenFileDialog).
En la tabla siguiente se describen las características de WPF que no es seguro ejecutar dentro de los límites del conjunto de permisos Zona de Internet.
Tabla 2: Características de WPF no seguras con confianza parcial
Área de la característica |
Característica |
---|---|
General |
Ventana (ventanas y cuadros de diálogo definidos por la aplicación) SaveFileDialog Sistema de archivos Acceso al Registro Arrastrar y colocar Serialización XAML (mediante XamlWriter.Save) Clientes de automatización de la interfaz de usuario Acceso a la ventana de origen (HwndHost) Compatibilidad plena con voz Interoperabilidad con formularios Windows Forms |
Elementos visuales |
Efectos de mapa de bits Codificación de imágenes |
Edición |
Portapapeles de formato de texto enriquecido Compatibilidad plena con XAML |
Programación de la confianza parcial
Para aplicaciones XBAP, el código que supera el conjunto de permisos predeterminado tendrá un comportamiento diferente según la zona de seguridad. En algunos casos, el usuario recibirá una advertencia cuando intente instalarla. El usuario puede continuar o cancelar la instalación. En la tabla siguiente se describe el comportamiento de la aplicación para cada zona de seguridad y lo que tiene que hacer para que la aplicación reciba plena confianza.
Zona de seguridad |
Behavior |
Obtener plena confianza |
---|---|---|
Equipo local |
Plena confianza automática |
No se requiere ninguna acción. |
Intranet y sitios de confianza |
Solicitar plena confianza |
Firmar la aplicación XBAP con un certificado para que el usuario vea el origen en el indicador. |
Internet |
Se produce un error "Confianza no concedida" |
Firmar la aplicación XBAP con un certificado. |
Nota |
---|
El comportamiento descrito en la tabla anterior es para las aplicaciones XBAP de plena confianza que no siguen el modelo de implementación de confianza de ClickOnce. |
En general, es probable que el código que puede superar los permisos concedidos sea código común que se comparte entre las aplicaciones independientes y hospedadas por explorador. CAS y WPF proporcionan varias técnicas para administrar este escenario.
Detectar permisos mediante CAS
En algunas situaciones, es posible que el código compartido en los ensamblados de bibliotecas se utilice en aplicaciones independientes y XBAPs. En estos casos, el código puede ejecutar funcionalidad que podría requerir más permisos de los permitidos por el conjunto de permisos de la aplicación. La aplicación puede detectar si tiene un permiso determinado o no mediante la seguridad de Microsoft .NET Framework. En particular, puede comprobar si tiene un permiso concreto llamando al método Demand en la instancia del permiso deseado. Esto se muestra en el ejemplo siguiente, que contiene código que consulta si tiene la capacidad de guardar un archivo en el disco local:
Imports System.IO ' File, FileStream, StreamWriter
Imports System.IO.IsolatedStorage ' IsolatedStorageFile
Imports System.Security ' CodeAccesPermission, IsolatedStorageFileStream
Imports System.Security.Permissions ' FileIOPermission, FileIOPermissionAccess
Imports System.Windows ' MessageBox
Namespace SDKSample
Public Class FileHandling
Public Sub Save()
If IsPermissionGranted(New FileIOPermission(FileIOPermissionAccess.Write, "c:\newfile.txt")) Then
' Write to local disk
Using stream As FileStream = File.Create("c:\newfile.txt")
Using writer As New StreamWriter(stream)
writer.WriteLine("I can write to local disk.")
End Using
End Using
Else
MessageBox.Show("I can't write to local disk.")
End If
End Sub
' Detect whether or not this application has the requested permission
Private Function IsPermissionGranted(ByVal requestedPermission As CodeAccessPermission) As Boolean
Try
' Try and get this permission
requestedPermission.Demand()
Return True
Catch
Return False
End Try
End Function
...
End Class
End Namespace
using System.IO; // File, FileStream, StreamWriter
using System.IO.IsolatedStorage; // IsolatedStorageFile
using System.Security; // CodeAccesPermission, IsolatedStorageFileStream
using System.Security.Permissions; // FileIOPermission, FileIOPermissionAccess
using System.Windows; // MessageBox
namespace SDKSample
{
public class FileHandling
{
public void Save()
{
if (IsPermissionGranted(new FileIOPermission(FileIOPermissionAccess.Write, @"c:\newfile.txt")))
{
// Write to local disk
using (FileStream stream = File.Create(@"c:\newfile.txt"))
using (StreamWriter writer = new StreamWriter(stream))
{
writer.WriteLine("I can write to local disk.");
}
}
else
{
MessageBox.Show("I can't write to local disk.");
}
}
// Detect whether or not this application has the requested permission
bool IsPermissionGranted(CodeAccessPermission requestedPermission)
{
try
{
// Try and get this permission
requestedPermission.Demand();
return true;
}
catch
{
return false;
}
}
...
}
}
Si una aplicación no tiene el permiso deseado, la llamada a Demand provocará una excepción de seguridad. De lo contrario, se ha concedido el permiso. IsPermissionGranted encapsula este comportamiento y devuelve true o false, según corresponda.
Degradación correcta de la funcionalidad
Poder detectar si el código tiene permiso para lo que necesita hacer es interesante para el código que se puede ejecutar desde zonas diferentes. Aunque detectar la zona es necesario, resulta mucho mejor proporcionar una alternativa al usuario, si es posible. Por ejemplo, una aplicación de plena confianza suele permitir al usuario crear los archivos que desee en cualquier lugar, mientras que una aplicación de confianza parcial sólo permite crearlos en almacenamiento aislado. Si el código para crear un archivo existe en un ensamblado compartido por aplicaciones de plena confianza (independientes) y de confianza parcial (hospedadas por explorador), y ambas aplicaciones desean que los usuarios puedan crear archivos, el código compartido debería detectar si se ejecuta con confianza parcial o plena antes de crear un archivo en la ubicación adecuada. En el código siguiente se muestran ambas operaciones.
Imports System.IO ' File, FileStream, StreamWriter
Imports System.IO.IsolatedStorage ' IsolatedStorageFile
Imports System.Security ' CodeAccesPermission
Imports System.Security.Permissions ' FileIOPermission, FileIOPermissionAccess
Imports System.Windows ' MessageBox
Namespace SDKSample
Public Class FileHandlingGraceful
Public Sub Save()
If IsPermissionGranted(New FileIOPermission(FileIOPermissionAccess.Write, "c:\newfile.txt")) Then
' Write to local disk
Using stream As FileStream = File.Create("c:\newfile.txt")
Using writer As New StreamWriter(stream)
writer.WriteLine("I can write to local disk.")
End Using
End Using
Else
' Persist application-scope property to
' isolated storage
Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
Using stream As New IsolatedStorageFileStream("newfile.txt", FileMode.Create, storage)
Using writer As New StreamWriter(stream)
writer.WriteLine("I can write to Isolated Storage")
End Using
End Using
End If
End Sub
' Detect whether or not this application has the requested permission
Private Function IsPermissionGranted(ByVal requestedPermission As CodeAccessPermission) As Boolean
Try
' Try and get this permission
requestedPermission.Demand()
Return True
Catch
Return False
End Try
End Function
...
End Class
End Namespace
using System.IO; // File, FileStream, StreamWriter
using System.IO.IsolatedStorage; // IsolatedStorageFile
using System.Security; // CodeAccesPermission
using System.Security.Permissions; // FileIOPermission, FileIOPermissionAccess
using System.Windows; // MessageBox
namespace SDKSample
{
public class FileHandlingGraceful
{
public void Save()
{
if (IsPermissionGranted(new FileIOPermission(FileIOPermissionAccess.Write, @"c:\newfile.txt")))
{
// Write to local disk
using (FileStream stream = File.Create(@"c:\newfile.txt"))
using (StreamWriter writer = new StreamWriter(stream))
{
writer.WriteLine("I can write to local disk.");
}
}
else
{
// Persist application-scope property to
// isolated storage
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
using (IsolatedStorageFileStream stream =
new IsolatedStorageFileStream("newfile.txt", FileMode.Create, storage))
using (StreamWriter writer = new StreamWriter(stream))
{
writer.WriteLine("I can write to Isolated Storage");
}
}
}
// Detect whether or not this application has the requested permission
bool IsPermissionGranted(CodeAccessPermission requestedPermission)
{
try
{
// Try and get this permission
requestedPermission.Demand();
return true;
}
catch
{
return false;
}
}
...
}
}
En muchos casos, debe existir una alternativa de confianza parcial.
En un entorno controlado, como una intranet, los marcos de trabajo administrados personalizados se pueden instalar en toda la base de clientes en global assembly cache (GAC). Estas bibliotecas pueden ejecutar código que requiere plena confianza y se puede hacer referencia a ellas en las aplicaciones que solo tienen confianza parcial mediante AllowPartiallyTrustedCallersAttribute (para obtener más información, vea Seguridad (WPF) y Estrategia de seguridad de WPF: Seguridad de plataforma).
Detección del host del explorador
Utilizar CAS para comprobar los permisos es una técnica conveniente cuando se necesita comprobar los permisos uno a uno. Sin embargo, esta técnica depende de que se detecten las excepciones como parte de procesamiento normal, algo que, en general, no se recomienda, y que puede dar lugar a problemas de rendimiento. En su lugar, si XAML browser application (XBAP) solamente se ejecuta dentro del espacio aislado de la Zona de Internet, puede usar la propiedad BrowserInteropHelper.IsBrowserHosted, que devuelve true para XAML browser applications (XBAPs).
Nota |
---|
IsBrowserHosted únicamente distingue si una aplicación se está ejecutando en un explorador, no detecta con qué conjunto de permisos se está ejecutando. |
Administrar permisos
De forma predeterminada, las XBAPs se ejecutan con confianza parcial (conjunto de permisos de Zona de Internet predeterminado). Sin embargo, dependiendo de los requisitos de la aplicación, es posible cambiar el conjunto de permisos predeterminado. Por ejemplo, si se inician XBAPs desde una intranet local, puede aprovechar un conjunto de permisos mayor, que se muestra en la tabla siguiente.
Tabla 3: Permisos de intranet local y de Internet
Permiso |
Atributo |
LocalIntranet |
Internet |
---|---|---|---|
DNS |
Tener acceso a los servidores DNS |
Sí |
No |
Variables de entorno |
Lectura |
Sí |
No |
Cuadros de diálogo de archivo |
Abra . |
Sí |
Sí |
Cuadros de diálogo de archivo |
Sin restricciones |
Sí |
No |
Almacenamiento aislado |
Aislamiento de ensamblados por usuario |
Sí |
No |
Almacenamiento aislado |
Aislamiento desconocido |
Sí |
Sí |
Almacenamiento aislado |
Cuota de usuario ilimitada |
Sí |
No |
Multimedia |
Audio, vídeo e imágenes seguros |
Sí |
Sí |
Impresión |
Impresión predeterminada |
Sí |
No |
Impresión |
Impresión segura |
Sí |
Sí |
Reflexión |
Emisión |
Sí |
No |
Seguridad |
Ejecución de código administrado |
Sí |
Sí |
Seguridad |
Declaración de permisos concedidos |
Sí |
No |
Interfaz de usuario |
Sin restricciones |
Sí |
No |
Interfaz de usuario |
Ventanas de nivel superior seguras |
Sí |
Sí |
Interfaz de usuario |
Portapapeles propio |
Sí |
Sí |
Web Browser |
Navegación de marcos segura en HTML |
Sí |
Sí |
Nota |
---|
Solo se permite cortar y pegar en la confianza parcial cuando sea iniciado por el usuario. |
Si necesita aumentar los permisos, es preciso modificar la configuración del proyecto y el manifiesto de la aplicación ClickOnce. Para obtener más información, vea Información general sobre las aplicaciones de explorador XAML de WPF. Los siguientes documentos también pueden ser útiles.
Mage.exe (Herramienta de generación y edición de manifiestos).
MageUI.exe (Herramienta de generación y edición de manifiestos, cliente gráfico).
Si XBAP requiere plena confianza, puede utilizar las mismas herramientas para aumentar los permisos solicitados, Aunque una XBAP solo recibirá plena confianza si se instala e inicia en el equipo local, la intranet o una dirección URL incluida en la lista de sitios permitidos o de confianza del explorador. Si la aplicación se instala desde la intranet o un sitio de confianza, el usuario recibirá el mensaje estándar de ClickOnce para notificarle los permisos elevados. El usuario puede continuar o cancelar la instalación.
Como alternativa, se puede utilizar el modelo de implementación de confianza de ClickOnce para realizar una implementación de plena confianza desde una zona de seguridad. Para obtener más información, vea Información general sobre la implementación de aplicaciones de confianza y Seguridad (WPF).