Безопасность частичного доверия в WPF

Как правило, интернет-приложениям следует ограничить прямой доступ к критическим системным ресурсам, чтобы избежать злонамеренного повреждения. По умолчанию HTML и клиентские языки сценариев на стороне клиента не могут получить доступ к критическим системным ресурсам. Поскольку браузерные приложения Windows Presentation Foundation (WPF) можно запускать из браузера, они должны соответствовать аналогичному набору ограничений. Для принудительного применения этих ограничений WPF полагается на возможности управления доступом для кода (CAS) и ClickOnce (см. раздел Стратегия безопасности WPF — безопасность платформы). По умолчанию браузерные приложения запрашивают набор разрешений CAS зоны Интернета, независимо от того, запускаются ли они из Интернета, из локальной интрасети или с локального компьютера. Приложения, выполняющиеся с набором разрешений меньшим, чем полный набор, называют выполняющимися с частичным доверием.

WPF предоставляет широкие возможности поддержки, чтобы гарантировать доступность максимального набора функций для безопасного использования в режиме частичного доверия, и наряду с CAS обеспечивает дополнительную поддержку для программирования в режиме частичного доверия.

Этот раздел состоит из следующих подразделов.

Поддержка частичного доверия функциями WPF

В следующей таблице перечислены обобщенные функции Windows Presentation Foundation (WPF), которые являются безопасными для использования в пределах набора разрешений зоны Интернета.

Таблица 1. Функции WPF, которые являются безопасными в режиме частичного доверия

Область функций Функция
Общие Окно обозревателя

Доступ к исходному сайту

IsolatedStorage (ограничение 512 КБ)

Поставщики UIAutomation

Система команд

Редакторы метода ввода (IME)

Перо планшетного компьютера и рукописный ввод

Моделирование перетаскивания с помощью событий захвата и перемещения мыши

OpenFileDialog

Десериализация XAML (посредством XamlReader.Load)
Веб-интеграция Диалоговое окно загрузки браузера

Навигация верхнего уровня, инициированная пользователем

mailto:links

Параметры универсального идентификатора ресурса (URI)

HTTPWebRequest

Содержимое WPF, размещенное в IFRAME

Размещение HTML-страниц одного веб-сайта с помощью Frame

Размещение HTML-страниц одного веб-сайта с помощью WebBrowser

Веб-службы (ASMX-файлы)

Веб-службы (с помощью Windows Communication Foundation)

Скрипты

Модель DOM
Визуальные элементы 2D- и 3D-графика

Анимация

Мультимедиа (исходный сайт и междоменные)

Обработка изображений/аудио/видео
Чтение FlowDocument

XPS-документы

Внедренные и системные шрифты

Шрифты CFF и TrueType
Редактирование Проверка орфографии

RichTextBox

Поддержка буфера обмена для обычного текста и рукописного ввода

Вставка, инициированная пользователем

Копирование выделенного содержимого
Элементы управления Общие элементы управления

В этой таблице приводится обобщенное описание функций WPF. Для получения более подробных сведений в Windows SDK задокументированы разрешения, необходимые каждому элементу в WPF. Кроме того, следующие функции содержат более подробные сведения, касающиеся выполнения при частичном доверии, включая некоторые особые аспекты.

В следующей таблице перечислены функции WPF, которые не являются безопасными для выполнения в пределах набора разрешений зоны Интернета.

Таблица 2. Функции WPF, которые не являются безопасными в режиме частичного доверия

Область функций Функция
Общие Окно (определенные приложением окна и диалоговые окна)

SaveFileDialog

Файловая система

Доступ к реестру

Перетаскивание

Сериализация XAML (через XamlWriter.Save)

Клиенты UIAutomation

Доступ к исходному окну (HwndHost)

Полная поддержка управления речью

Взаимодействие с Windows Forms
Визуальные элементы Эффекты для точечных рисунков

Кодирование изображений
Редактирование Буфер обмена формата RTF

Полная поддержка XAML

Программирование в режиме частичного доверия

Что касается приложений XBAP, код, превышающий набор разрешений по умолчанию, будет выполняться по-разному в зависимости от зоны безопасности. В некоторых случаях пользователь получит предупреждение при попытке установить приложение. Пользователь может выбрать продолжение или отмену установки. В следующей таблице описаны поведение приложения для каждой зоны безопасности и действия, необходимые для получения приложением полного доверия.

Предупреждение

Для работы XBAPs требуются устаревшие браузеры, такие как Internet Explorer и старые версии Firefox. Эти старые браузеры обычно не поддерживаются в Windows 10 и Windows 11. Современные браузеры больше не поддерживают технологию, необходимую для приложений XBAP из-за рисков безопасности. Подключаемые модули, поддерживающие XBAP, больше не поддерживаются. Дополнительные сведения см. в разделе часто задаваемые вопросы о приложениях, размещенных в браузере WPF (XBAP).

Зона безопасности Поведение Получение полного доверия
Локальный компьютер Автоматическое получение полного доверия Никаких действий не требуется.
Интрасеть и надежные веб-сайты Запрос полного доверия Подпишите приложение XBAP с помощью сертификата, чтобы пользователь видел источник в запросе.
Интернет Сбой с сообщением "Доверие не оказано" Подпишите приложение XBAP с помощью сертификата.

Примечание.

Поведение, описанное в предыдущей таблице, относится к приложениям XBAP с полным доверием, не следующим модели доверенного развертывания ClickOnce.

В общем случае код, который может превышать допустимые разрешения, вероятнее всего, является общим кодом, который совместно используется автономными и браузерными приложениями. CAS и WPF обеспечивают несколько методик для таких случаев.

Определение разрешений с помощью CAS

В некоторых случаях общий код в сборках библиотеки будет использоваться как автономными приложениями, так и XBAP. В этих случаях код может выполнять функции, которые могут потребовать больше разрешений, чем позволяет набор разрешений, присвоенный приложению. Приложение может определять, есть ли у него определенные разрешения, используя систему безопасности Microsoft .NET Framework. В частности, оно может проверить наличие определенного разрешения, вызвав метод Demand для экземпляра нужного разрешения. Это показано в следующем примере, который содержит код, запрашивающий возможность сохранить файл на локальный диск.

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

Если приложение не имеет нужных разрешений, вызов Demand создаст исключение безопасности. В противном случае разрешение будет предоставлено. IsPermissionGranted инкапсулирует это поведение и возвращает значение true или false соответствующим образом.

Постепенное снижение функциональности

Возможность обнаружения у кода разрешений на выполнение действия представляет интерес для кода, который может выполняться из разных зон. Обнаружение зоны — это один из аспектов, однако рекомендуется по возможности предоставить пользователю альтернативу. Например, приложение с полным доверием обычно позволяет пользователям создавать файлы в любом расположении, тогда как приложение с частичным доверием может создавать файлы только в изолированном хранилище. Если код для создания файла существует в сборке, которая совместно используется приложениями с полным доверием (автономными) и приложениями с частичным доверием (размещенными в браузере), и оба приложения должны обеспечивать функцию создания файлов пользователем, общий код должен определить, выполняется ли он в режиме частичного или полного доверия перед созданием файла в соответствующем расположении. Оба варианта демонстрируются в следующем коде.

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

Во многих случаях вы сможете найти альтернативу частичному доверию.

В управляемой среде, например, в интрасети, для всех клиентов в глобальном кэше сборок (GAC) можно установить настраиваемые управляемые структуры. Эти библиотеки могут выполнять код, который требует полного доверия, и на них может ссылаться код из приложений, которым разрешено только частичное доверие, используя атрибут AllowPartiallyTrustedCallersAttribute (дополнительные сведения см. в разделе Безопасность и Стратегия безопасности WPF — безопасность платформы).

Обнаружение узла браузера

Использование CAS для проверки разрешений является надлежащим способом, если необходимо выполнять проверку для отдельных разрешений. Тем не менее эта методика зависит от перехвата исключений в рамках нормальной обработки, что не рекомендуется в общем и может вызывать проблемы производительности. Вместо этого, если приложение браузера XAML (XBAP) выполняется только в песочнице зоны Интернета, можно использовать свойство BrowserInteropHelper.IsBrowserHosted, которое возвращает значение True для приложений браузера XAML (XBAP).

Предупреждение

Для работы XBAPs требуются устаревшие браузеры, такие как Internet Explorer и старые версии Firefox. Эти старые браузеры обычно не поддерживаются в Windows 10 и Windows 11. Современные браузеры больше не поддерживают технологию, необходимую для приложений XBAP из-за рисков безопасности. Подключаемые модули, поддерживающие XBAP, больше не поддерживаются. Дополнительные сведения см. в разделе часто задаваемые вопросы о приложениях, размещенных в браузере WPF (XBAP).

Примечание.

IsBrowserHosted служит только для определения того, выполняется ли приложение в браузере, и не может определить набор разрешений приложения.

Управление разрешениями

По умолчанию XBAP выполняются в режиме частичного доверия (набор разрешений зоны Интернета по умолчанию). Тем не менее в зависимости от требований приложения можно изменить набор разрешений по умолчанию. Например, если XBAP запускается из локальной интрасети, оно может воспользоваться преимуществом расширенного набора разрешений, как показано в следующей таблице.

Предупреждение

Для работы XBAPs требуются устаревшие браузеры, такие как Internet Explorer и старые версии Firefox. Эти старые браузеры обычно не поддерживаются в Windows 10 и Windows 11. Современные браузеры больше не поддерживают технологию, необходимую для приложений XBAP из-за рисков безопасности. Подключаемые модули, поддерживающие XBAP, больше не поддерживаются. Дополнительные сведения см. в разделе часто задаваемые вопросы о приложениях, размещенных в браузере WPF (XBAP).

Таблица 3. Наборы разрешений LocalIntranet и Internet

Разрешение Атрибут LocalIntranet Интернет
DNS Доступ к DNS-серверам Да Нет
Переменные среды Читать Да Нет
Диалоговые окна для работы с файлами При открытии Да Да
Диалоговые окна для работы с файлами С неограниченным доступом Да Нет
Изолированное хранилище Изоляция сборки по пользователю Да Нет
Изолированное хранилище Неизвестная изоляция Да Да
Изолированное хранилище Неограниченная квота для пользователя Да Нет
Средства массовой информации Безопасные аудио-, видеоданные и изображения Да Да
Печать Печать по умолчанию Да Нет
Печать Безопасная печать Да Да
Отражение Вывод Да Нет
Контроль доступа Выполнение управляемого кода Да Да
Контроль доступа Утверждение предоставленных разрешений Да Нет
Пользовательский интерфейс С неограниченным доступом Да Нет
Пользовательский интерфейс Безопасные окна верхнего уровня Да Да
Пользовательский интерфейс Собственный буфер обмена Да Да
Веб-браузер Безопасная навигация по фреймам в HTML Да Да

Примечание.

Вырезание и вставка разрешены только в режиме частичного доверия при инициации пользователем.

Если вам требуется повысить уровень разрешений, необходимо изменить параметры проекта и манифест приложения ClickOnce. Дополнительные сведения см. в разделе Общие сведения о приложениях браузера WPF XAML. Следующие документы также могут быть полезны.

Если ваше приложение XBAP требует полного доверия, можно использовать те же средства для предоставления запрошенных разрешений. Тем не менее, XBAP получит полное доверие, только если оно установлено и запущено на локальном компьютере, из интрасети или с URL-адреса, указанного в списке доверенных или разрешенных сайтов браузера. Если приложение установлено из интрасети или с доверенного сайта, пользователь получит стандартный запрос ClickOnce, уведомляющий о повышенных разрешениях. Пользователь может выбрать продолжение или отмену установки.

Кроме того, модель доверенного развертывания ClickOnce можно использовать для полностью доверенного развертывания из любой зоны безопасности. Дополнительные сведения см. в разделе Общие сведения о развертывании доверенных приложений и Безопасность.

См. также