Seguridad de confianza parcial de WPF

En general, deben restringirse las aplicaciones de Internet para que no tengan acceso directo a recursos críticos del sistema y así evitar daños malintencionados. De forma predeterminada, los lenguajes HTML y de scripting del lado cliente no tienen acceso a recursos críticos del sistema. Dado que las aplicaciones de Windows Presentation Foundation (WPF) hospedadas en explorador se pueden iniciar desde el navegador, deben cumplir un conjunto similar de restricciones. Para aplicar estas restricciones, WPF se basa en Seguridad de acceso del código (CAS) y ClickOnce (consulte Estrategia de seguridad de WPF: Seguridad de plataforma). De forma predeterminada, las aplicaciones hospedadas en explorador solicitan el conjunto de permisos CAS de la zona de Internet, independientemente de si se inician desde Internet, la intranet local o el equipo local. Las aplicaciones que se ejecutan con menos permisos que el conjunto completo de permisos se dice que se ejecutan con confianza parcial.

WPF proporciona una amplia variedad de compatibilidad para garantizar que se puede usar con seguridad tanta funcionalidad como sea posible con confianza parcial y, junto con CAS, proporciona compatibilidad adicional para la programación de confianza parcial.

Este tema contiene las siguientes secciones:

Compatibilidad de confianza parcial de las características de WPF

En la tabla siguiente se enumeran las características de alto nivel de Windows Presentation Foundation (WPF) que son seguras de usar dentro de los límites del conjunto de permisos de la zona de Internet.

Tabla 1: Características de WPF que son seguras en confianza parcial

Área de características Característica
General Ventana del explorador

Acceso al sitio de origen

IsolatedStorage (límite de 512 KB)

Proveedores de UIAutomation

Comandos

Editores de métodos de entrada (IMEs)

Lápiz y entrada de lápiz de tableta

Movimiento simulado de arrastrar y colocar con los eventos de captura y movimiento del mouse

OpenFileDialog

Deserialización XAML (mediante XamlReader.Load)
Integración en Internet Cuadro de diálogo de descarga del explorador

Navegación iniciada por el usuario de nivel superior

mailto:links

Parámetros de identificador de recursos uniforme

HTTPWebRequest

Contenido de WPF hospedado en un IFRAME

Hospedaje de páginas HTML del mismo sitio con marco

Hospedaje de páginas HTML del mismo sitio con WebBrowser

Servicios web (ASMX)

Servicios Web (con Windows Communication Foundation)

Scripting

Modelo de objetos de documento
Objetos visuales 2D y 3D

Animación

Multimedia (sitio de origen y entre dominios)

Creación de imágenes, audio y vídeo
Lectura FlowDocuments

Documentos XPS

Fuentes insertadas y del sistema

Fuentes CFF y TrueType
Edición Revisión ortográfica

RichTextBox

Compatibilidad con texto sin formato y portapapeles de entrada de lápiz

Pegado iniciado por el usuario

Copiar contenido seleccionado
Controles Controles generales

En esta tabla se tratan las características de WPF de alto nivel. Para obtener información detallada, Windows SDK documenta los permisos que necesita cada miembro en WPF. Además, las características siguientes ofrecen más información detallada sobre la ejecución de confianza parcial, incluidas algunas consideraciones especiales.

En la tabla siguiente se indican las características de WPF que no se pueden ejecutar con seguridad dentro de los límites del conjunto de permisos de la zona de Internet.

Tabla 2: Características de WPF que no son seguras en confianza parcial

Área de características 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 UIAutomation

Acceso a la ventana de origen (HwndHost)

Compatibilidad total con Voz

Interoperabilidad de Windows Forms
Objetos visuales Efectos de imagen

Codificación de imagen
Edición Portapapeles con formato de texto enriquecido

Compatibilidad total con XAML

Programación de 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 al intentar instalarlo. El usuario puede elegir continuar con la instalación o cancelarla. En la tabla siguiente se describe el comportamiento de la aplicación para cada zona de seguridad y qué se debe hacer para que la aplicación reciba plena confianza.

Advertencia

Las aplicaciones XBAP requieren exploradores heredados para funcionar, como Internet Explorer y versiones anteriores de Firefox. Estos exploradores anteriores no suelen ser compatibles con Windows 10 y Windows 11. Los exploradores modernos ya no admiten la tecnología necesaria para las aplicaciones XBAP debido a riesgos de seguridad. Los complementos que habilitan XBAPs ya no se admiten. Para obtener más información, vea Preguntas más frecuentes sobre las aplicaciones hospedadas en explorador (XBAP) de WPF.

Zona de seguridad Comportamiento Obtener plena confianza
Equipo local Plena confianza automática No se requiere ninguna acción.
Intranet y sitios de confianza Pedir plena confianza Firme la aplicación XBAP con un certificado para que el usuario vea el origen en la petición.
Internet Error: "Confianza no concedida" Firme la aplicación XBAP con un certificado.

Nota:

El comportamiento descrito en la tabla anterior es para XBAP de plena confianza que no siguen el modelo de implementación de confianza ClickOnce.

En general, el código que puede superar los permisos permitidos es probable que sea código común compartido entre aplicaciones independientes y hospedadas en explorador. CAS y WPF ofrecen varias técnicas para administrar este escenario.

Detectar permisos con CAS

En algunas situaciones, es posible que aplicaciones independientes y XBAP usen código compartido en ensamblados de biblioteca. En estos casos, es posible que el código ejecute funcionalidades que podrían necesitar más permisos que los que se incluyen en el conjunto de permisos que concede la aplicación. La aplicación puede detectar si tiene un permiso determinado mediante la seguridad de Microsoft .NET Framework. Específicamente, puede comprobar si tiene un permiso específico 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:

using System.IO;
using System.IO.IsolatedStorage;
using System.Security;
using System.Security.Permissions;
using System.Windows;

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;
            }
        }


Imports System.IO
Imports System.IO.IsolatedStorage
Imports System.Security
Imports System.Security.Permissions
Imports System.Windows

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

Si una aplicación no tiene el permiso deseado, la llamada a Demand iniciará una excepción de seguridad. De lo contrario, se concedió 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 código que se puede ejecutar desde distintas zonas. Detectar la zona es una cosa, pero es mucho mejor proporcionar una alternativa para el usuario, si es posible. Por ejemplo, una aplicación de plena confianza normalmente permite a los usuarios crear archivos donde quieran, mientras que una aplicación de confianza parcial solo permite crear archivos en almacenamiento aislado. Si el código para crear un archivo existe en un ensamblado que comparten aplicaciones (independientes) de plena confianza y aplicaciones (hospedadas en explorador) de confianza parcial, y ambas aplicaciones quieren que los usuarios puedan crear archivos, el código compartido debe detectar si se ejecuta con confianza plena o parcial antes de crear el archivo en la ubicación adecuada. En el código siguiente se muestran ambas opciones.

using System.IO;
using System.IO.IsolatedStorage;
using System.Security;
using System.Security.Permissions;
using System.Windows;

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;
            }
        }


Imports System.IO
Imports System.IO.IsolatedStorage
Imports System.Security
Imports System.Security.Permissions
Imports System.Windows

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

En muchos casos, debería poder encontrar una alternativa de confianza parcial.

En un entorno controlado, como una intranet, los marcos administrados personalizados se pueden instalar a través de la base de cliente en el caché global de ensamblados (GAC). Estas bibliotecas pueden ejecutar código que necesite plena confianza y se puede hacer referencia a ellas desde aplicaciones que solo tengan permiso de confianza parcial mediante AllowPartiallyTrustedCallersAttribute (para más información, consulte Seguridad (WPF) y Estrategia de seguridad de WPF: Seguridad de plataforma).

Detección de host del explorador

El uso de CAS para buscar permisos es una técnica conveniente cuando se tienen que realizar comprobaciones por permiso. Sin embargo, esta técnica depende de la detección de excepciones como parte del procesamiento normal, que, en general, no se recomienda y puede tener problemas de rendimiento. En su lugar, si la aplicación del explorador XAML (XBAP) solo se ejecuta dentro del espacio aislado de la zona de Internet, puedes usar la propiedad BrowserInteropHelper.IsBrowserHosted, que devuelve true para las aplicaciones del explorador XAML (XBAP).

Advertencia

Las aplicaciones XBAP requieren exploradores heredados para funcionar, como Internet Explorer y versiones anteriores de Firefox. Estos exploradores anteriores no suelen ser compatibles con Windows 10 y Windows 11. Los exploradores modernos ya no admiten la tecnología necesaria para las aplicaciones XBAP debido a riesgos de seguridad. Los complementos que habilitan XBAPs ya no se admiten. Para obtener más información, vea Preguntas más frecuentes sobre las aplicaciones hospedadas en explorador (XBAP) de WPF.

Nota:

IsBrowserHosted solo distingue si una aplicación se ejecuta en un navegador, no el conjunto de permisos con el que se está ejecutando la aplicación.

Administrar permisos

De forma predeterminada, XBAP se ejecuta con confianza parcial (conjunto de permisos predeterminado de la zona de Internet). Sin embargo, según los requisitos de la aplicación, es posible cambiar el conjunto de permisos predeterminado. Por ejemplo, si un XBAP se inicia desde una intranet local, puede sacar provecho de un conjunto de permisos mayor; esto se muestra en la tabla siguiente.

Advertencia

Las aplicaciones XBAP requieren exploradores heredados para funcionar, como Internet Explorer y versiones anteriores de Firefox. Estos exploradores anteriores no suelen ser compatibles con Windows 10 y Windows 11. Los exploradores modernos ya no admiten la tecnología necesaria para las aplicaciones XBAP debido a riesgos de seguridad. Los complementos que habilitan XBAPs ya no se admiten. Para obtener más información, vea Preguntas más frecuentes sobre las aplicaciones hospedadas en explorador (XBAP) de WPF.

Tabla 3: Permisos de LocalIntranet e Internet

Permiso Atributo LocalIntranet Internet
DNS Servidores DNS de acceso No
Variables de entorno Lectura No
Cuadros de diálogo de archivo Abrir
Cuadros de diálogo de archivo Sin restricciones No
Almacenamiento aislado Aislamiento de ensamblados por el usuario No
Almacenamiento aislado Aislamiento desconocido
Almacenamiento aislado Cuota de usuario ilimitada No
Medios Imágenes, vídeo y audio seguros
Impresión Impresión predeterminada No
Impresión Impresión segura
Reflexión Emitir No
Seguridad Ejecución de código administrado
Seguridad Permisos de aserción concedidos No
Interfaz de usuario Sin restricciones No
Interfaz de usuario Ventanas seguras de nivel superior
Interfaz de usuario Portapapeles propio
Explorador web Navegación de marcos segura a HTML

Nota

Cortar y pegar solo se permite con confianza parcial cuando el usuario inicia la acción.

Si necesita aumentar los permisos, debe cambiar la configuración del proyecto y el manifiesto de 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.

Si su XBAP necesita plena confianza, puede usar las mismas herramientas para aumentar los permisos solicitados. Aunque un XBAP solo recibirá plena confianza si se instala y se inicia desde un equipo local, la intranet o una dirección URL que aparezca en los sitios de confianza o permitidos del navegador. Si la aplicación se instala desde la intranet o un sitio de confianza, el usuario recibirá el mensaje estándar de ClickOnce, que le notificará los permisos elevados. El usuario puede elegir continuar con la instalación o cancelarla.

Como alternativa, puede usar el modelo de implementación de confianza de ClickOnce para realizar una implementación de plena confianza desde cualquier zona de seguridad. Para más información, consulte Introducción a la implementación de aplicaciones de confianza y Seguridad (WPF).

Vea también