Изолированное хранилище

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

Внимание

Изолированное хранилище недоступно для приложений Магазина Windows 8.x. Вместо этого используйте классы данных приложений в пространствах имен Windows.Storage, включенных в API среды выполнения Windows для хранения локальных данных и файлов. Дополнительные сведения см. в статье Доступ к данным приложения в Центре разработки для Windows.

Секции данных и хранилища

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

В изолированном хранилище данные всегда изолированы по пользователю и сборке. Сборка идентифицируется такими учетными данными, как идентичность, определяемая источником или строгим именем сборки. Данные также могут быть изолированы по домену приложения при помощи подобных учетных данных.

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

Квоты для изолированного хранилища

Квота — это ограничение доступного для использования объема изолированного хранилища. Квота учитывает байты файлового пространства, а также служебные данные, связанные с каталогом и другой информацией в хранилище. Изолированное хранилище использует квоты разрешения, которые представляют собой допустимые пределы хранения, устанавливаемые посредством объектов IsolatedStoragePermission . При попытке записать данные, которые превышают квоту, возникает исключение IsolatedStorageException. Какие разрешения даются коду, определяет политика безопасности, которую можно менять с помощью средства настройки .NET Framework (Mscorcfg.msc). Код, которому предоставлено IsolatedStoragePermission, ограничен в использовании хранилища, не превышающего размер, заданный свойством UserQuota. Тем не менее, поскольку код может обходить квоты разрешения, используя различные удостоверения пользователя, эти квоты в большей степени имеют характер рекомендаций по работе кода, нежели выступают в роли строгих ограничений.

К роуминговым хранилищам квоты не применяются. По этой причине для их использования код должен располагать разрешениями несколько более высокого уровня. Значения перечисления AssemblyIsolationByRoamingUser и DomainIsolationByRoamingUser определяют разрешение на использование изолированного хранилища для пользователя с функцией перемещения.

безопасный доступ

Использование изолированного хранения позволяет частично доверенным приложениям сохранять данные под контролем политики безопасности компьютера. Это особенно полезно для загружаемых компонентов, которые пользователь может захотеть запускать с осторожностью. Политика безопасности редко предоставляет такому коду право доступа к файловой системе с использованием стандартных механизмов ввода-вывода. Однако по умолчанию код, запускаемый с локального компьютера, из локальной или глобальной сети получает право на использование изолированного хранилища.

Администраторы могут ограничивать размеры изолированного хранилища, доступного приложению или пользователю, в зависимости от соответствующего уровня доверия. Кроме того, администраторы могут удалить все хранящиеся данные. Чтобы создать изолированное хранилище или получить доступ к нему, коду необходимо предоставить соответствующее разрешение IsolatedStorageFilePermission .

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

Для управления доступом к изолированному хранилищу общая среда выполнения использует объекты IsolatedStorageFilePermission. Каждый объект имеет свойства, которые определяют следующие значения:

  • Разрешенное использование, которое указывает тип разрешенного доступа. Значения являются членами перечисления IsolatedStorageContainment . Дополнительные сведения об этих значениях см. в таблице в следующем разделе.

  • Квота хранилища, описанная в предыдущем разделе.

Среда выполнения требует разрешения IsolatedStorageFilePermission, когда код впервые пытается открыть хранилище. Решение о предоставлении этого разрешения определяется с учетом надежности кода. Если разрешение выдается, значения квоты использования и хранилища определяются политикой безопасности и запросом кода на получение разрешения IsolatedStorageFilePermission. Политика безопасности задается с помощью средства настройки .NET Framework (Mscorcfg.msc). Все вызовы в стеке вызовов проверяются, чтобы удостовериться, что у каждого вызова есть, по крайней мере, соответствующий разрешённый уровень использования. Среда выполнения также проверяет наличие квоты у кода, открывшего или создавшего хранилище, в которое записывается файл. Если все эти условия выполнены, то выдается разрешение. Квота проверяется каждый раз при записи файла в хранилище.

Коду приложения не нужно запрашивать разрешение, поскольку среда CLR выдаст соответствующее разрешение IsolatedStorageFilePermission , исходя из политики безопасности. Однако имеет смысл запрашивать определенные разрешения для своего приложения, включая IsolatedStorageFilePermission.

Разрешенное использование и угрозы безопасности

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

Разрешенное использование Типы изоляции Риски безопасности
None Нет разрешения на изолированное хранилище. Влияния на безопасность нет.
DomainIsolationByUser Изоляция по пользователям, доменам и сборкам. Каждая сборка имеет отдельное вложенное хранилище внутри домена. Хранилища, использующие это разрешение, также неявно изолируются компьютером. Этот уровень разрешения оставляет возможность несанкционированного чрезмерного использования ресурсов, хотя применение квот делает это затруднительным. Этот процесс называется атакой типа "отказ в обслуживании".
DomainIsolationByRoamingUser То же, что и DomainIsolationByUser, однако хранилище сохраняется в перемещаемое расположение, если применяются перемещаемые профили пользователей и не применяются квоты. Поскольку квоты приходится отключать, то ресурсы хранения более уязвимы к атаке типа "отказ в обслуживании".
AssemblyIsolationByUser Изоляция для пользователей и сборок. Хранилища, использующие это разрешение, также неявно изолируются компьютером. На этом уровне применяются квоты для предотвращения атак типа "отказ в обслуживании". Та же сборка в другом домене может иметь доступ к хранилищу, что может привести к утечке информации между приложениями.
AssemblyIsolationByRoamingUser То же, что и AssemblyIsolationByUser, однако хранилище сохраняется в перемещаемое расположение, если применяются перемещаемые профили пользователей и не применяются квоты. То же, что и AssemblyIsolationByUser, но без квот; риск атак типа "отказ в обслуживании" возрастает.
AdministerIsolatedStorageByUser Изоляция пользователем. Обычно этот уровень разрешения используют только средства администрирования или отладки. Доступ с этим уровнем разрешения позволяет коду просматривать или удалять любые файлы и каталоги изолированного хранилища пользователя (независимо от изоляции сборки). Риски, помимо прочего, включают утечку информации и потерю данных.
UnrestrictedIsolatedStorage Изоляция для всех пользователей, доменов и сборок. Обычно этот уровень разрешения используют только средства администрирования или отладки. Это разрешение создает возможность полного компрометации всех изолированных хранилищ для всех пользователей.

Безопасность компонентов изолированного хранилища по отношению к ненадежным данным

Этот раздел применяется к следующим платформам.

  • .NET Framework (все версии)
  • .NET Core 2.1+
  • .NET 5.+

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

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

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

Компоненты или приложения, вызывающие любой из следующих интерфейсов API, считывают данные из области видимости на уровне компьютера.

Средство изолированного хранилищаstoreadm.exe подвергается воздействию при вызове с параметром /machine, как показано в следующем коде.

storeadm.exe /machine [any-other-switches]

Это средство изолированного хранилища предоставляется в составе Visual Studio и пакета SDK для .NET Framework.

Если приложение не связано с вызовами предыдущих API или если рабочий процесс не подразумевает вызов storeadm.exe подобным образом, этот документ не применяется.

Влияние в многопользовательских средах

Как упоминалось ранее, влияние этих API на безопасность связано с тем, что данные, записанные из одной среды доверия, считываются из другой среды доверия. Изолированное хранилище обычно использует для чтения и записи данных одно из трех расположений.

  1. %LOCALAPPDATA%\IsolatedStorage\: например, C:\Users\<username>\AppData\Local\IsolatedStorage\для User области.
  2. %APPDATA%\IsolatedStorage\: например, C:\Users\<username>\AppData\Roaming\IsolatedStorage\для User|Roaming области.
  3. %PROGRAMDATA%\IsolatedStorage\: например, C:\ProgramData\IsolatedStorage\для Machine области.

Первые два расположения изолированы для каждого пользователя. Windows гарантирует, что разные учетные записи пользователей на одном компьютере не смогут получить доступ к папкам профиля других пользователей. Две разные учетные записи пользователей, использующие хранилища User или User|Roaming, не будут видеть данные друг друга и не смогут повлиять на них.

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

Указанные выше пути могут отличаться в зависимости от используемой версии Windows.

Теперь давайте рассмотрим многопользовательскую систему с двумя зарегистрированными пользователями — Мэллори и Бобом. Мэллори имеет доступ к своему каталогу профиля пользователя C:\Users\Mallory\ и может получить доступ к общему расположению хранилища на уровне компьютера C:\ProgramData\IsolatedStorage\. Она не может получить доступ к каталогу профиля пользователя Боба C:\Users\Bob\.

Если Мэллори захочет атаковать Боба, она может записать данные в хранилище общесистемного уровня, а затем попытаться вынудить Боба выполнить чтение из этого хранилища. Когда Боб запускает приложение, которое считывает данные из этого хранилища, оно будет работать с данными, помещенными туда Мэллори, но в контексте учетной записи Боба. В оставшейся части этого документа описаны различные векторы атаки, а также действия, которые приложения могут предпринимать для снижения риска таких атак.

Примечание.

Чтобы произвести подобную атаку, Мэллори потребуется следующее.

  • Учетная запись пользователя на компьютере.
  • Возможность поместить файл в известное расположение в файловой системе.
  • Знание того, что в определенный момент Боб запустит приложение, которое попытается считать эти данные.

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

Повышение привилегий

Атака, основанная на повышении привилегий, происходит, когда приложение Боба считывает файл Мэллори и автоматически пытается предпринять действия на основе содержимого этого пейлоуда. Представьте себе приложение, которое считывает содержимое сценария запуска из хранилища на уровне компьютера и передает эти данные в Process.Start. Если Мэллори может поместить вредоносный сценарий в хранилище на уровне компьютера, то при запуске Бобом его приложения происходит следующее.

  • Его приложение анализирует и запускает вредоносный сценарий Мэллори в контексте профиля пользователя Боба.
  • Мэллори получает доступ к учетной записи Боба на локальном компьютере.

Отказ в обслуживании

Атака типа отказ в обслуживании происходит, когда приложение Боба считывает файл Мэллори и аварийно завершает работу либо перестает работать правильно. Снова представьте себе приложение, упомянутое ранее, которое пытается проанализировать сценарий запуска из хранилища на уровне компьютера. Если Мэллори может поместить файл с некорректным содержимым в хранилище на уровне компьютера, она может:

  • заставить приложение Боба вызывать исключение на раннем этапе процедуры запуска;
  • предотвратить успешный запуск приложения из-за этого исключения.

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

Раскрытие информации

Атака, основанная на раскрытии информации, происходит, когда Мэллори может вынудить Боба раскрыть содержимое файла, к которому у Мэллори в общем случае нет доступа. Представьте себе, что Боб имеет секретный файл C:\Users\Bob\secret.txt, который Мэллори хочет прочитать. Она знает путь к этому файлу, но не может прочитать его, так как Windows не позволяет ей получить доступ к каталогу профиля пользователя Боба.

Вместо этого Мэллори помещает жесткую ссылку в хранилище на системном уровне. Это особый тип файла, который не имеет содержимого, а указывает на другой файл на диске. Попытка считать файл жесткой ссылки приведет к считыванию содержимого файла, на который ссылается эта ссылка. После создания жесткой связи Мэллори по-прежнему не может прочитать содержимое файла, так как у нее нет доступа к целевому объекту (C:\Users\Bob\secret.txt) этой связи. Однако у Боба есть доступ к этому файлу.

Когда приложение Боба считывает данные из хранилища на уровне компьютера, оно непреднамеренно считывает содержимое его файла secret.txt, как если бы этот файл находился в хранилище на уровне компьютера. Когда приложение Боба завершает работу, если он пытается повторно сохранить файл в хранилище на уровне компьютера, он в конечном итоге помещает фактическую копию файла в каталог *C:\ProgramData\IsolatedStorage*. Так как этот каталог доступен для чтения любым пользователем на компьютере, Мэллори может читать содержимое файла.

Рекомендации по защите от подобных атак

Важно. Если в вашей среде несколько взаимно недоверяющих пользователей, не вызывайте API IsolatedStorageFile.GetEnumerator(IsolatedStorageScope.Machine) и не используйте средствоstoreadm.exe /machine /list. Оба этих компонента предполагают работу с надежными данными. Если злоумышленник может внедрить вредоносный код в хранилище данных на уровне компьютера, это может привести к атаке с целью повышения привилегий в контексте пользователя, который выполняет эти команды.

При работе в многопользовательской среде рекомендуется рассмотреть возможность использования функций изолированного хранилища, предназначенных для области Компьютер. Если приложению необходимо считывать данные из общесистемного местоположения, предпочтительно считывать данные из такого места, которое доступно для записи только учетным записям администратора. Каталог %PROGRAMFILES% и куст реестра HKLM являются примерами расположений, которые доступны для записи только администраторам, а для чтения — всем пользователям. Поэтому данные, считанные из этих мест, считаются надежными.

Если приложение должно использовать область Компьютер в многопользовательской среде, проверяйте содержимое любого файла, считываемого из хранилища на уровне компьютера. Если приложение десериализует графы объектов из таких файлов, рекомендуется использовать более безопасные сериализаторы, такие как XmlSerializer, вместо опасных, таких как BinaryFormatter или NetDataContractSerializer. Соблюдайте осторожность при работе с глубоко вложенными графами объектов или графами объектов, выделяющими ресурсы на основе содержимого файла.

Расположения изолированных хранилищ

В некоторых случаях рекомендуется проверять изменения в изолированном хранилище, используя файловую систему операционной системы. Возможно, вам будет интересно узнать о расположении файлов изолированного хранилища. Место их размещения зависит от операционной системы. Ниже в таблице приведены корневые расположения, где создается изолированное хранилище на некоторых распространенных операционных системах. Найдите директории Microsoft\IsolatedStorage в этой корневой директории. Для того чтобы отобразить изолированное хранилище в файловой системе, нужно изменить настройки папки, установив для нее отображение скрытых файлов и папок.

Операционная система Местоположение в файловой системе
Windows 2000, Windows XP, Windows Server 2003 (обновление Windows NT 4.0) Хранилища с поддержкой роуминга =

<SYSTEMROOT>\Profiles\<user>\Данные приложений

Неперемещаемые хранилища =

<SYSTEMROOT>\Profiles\<user>\Локальные настройки\Данные приложений
Windows 2000 — чистая установка (и обновление с Windows 98 и Windows NT 3.51) Хранилища с поддержкой роуминга =

<SYSTEMDRIVE>\Documents and Settings\<пользователь>\Application Data

Неперемещаемые хранилища =

<SYSTEMDRIVE>\Документы и настройки\<пользователь>\Локальные настройки\Данные приложения
Windows XP, Windows Server 2003 — чистая установка (или обновление с Windows 2000 и Windows 98) Хранилища с поддержкой роуминга =

<SYSTEMDRIVE>\Documents and Settings\<пользователь>\Application Data

Неперемещаемые хранилища =

<SYSTEMDRIVE>\Документы и настройки\<пользователь>\Локальные настройки\Данные приложения
Windows 8, Windows 7, Windows Server 2008, Windows Vista Хранилища с поддержкой роуминга =

<SYSTEMDRIVE>\Users\<user>\AppData\Roaming

Неперемещаемые хранилища =

<SYSTEMDRIVE>\Users\<user>\AppData\Local

Создание, перечисление и удаление изолированного хранилища

В составе .NET есть три класса в пространстве имен System.IO.IsolatedStorage, которые помогают выполнять задачи, включающие изолированное хранилище.

  • КлассIsolatedStorageFile, производный от класса System.IO.IsolatedStorage.IsolatedStorage , обеспечивает базовую функциональность для управления хранимыми сборками и файлами приложений. Экземпляр класса IsolatedStorageFile служит для представления единичного хранилища, расположенного в файловой системе.

  • КлассIsolatedStorageFileStream , производный от класса System.IO.FileStream , предоставляет доступ к файлам, расположенным в хранилище.

  • Перечисление IsolatedStorageScope — это механизм, позволяющий создавать и выбирать магазин с необходимым типом изоляции.

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

Несколько примеров распространенных задач, связанных с изолированным хранилищем, см. в практических руководствах, перечисленных в разделе Связанные разделы.

Сценарии изолированного хранилища

Изолированное хранилище может оказаться полезным во многих случаях, в том числе в следующих четырех ситуациях:

  • Загрузенные элементы управления. Элементам управления, загружаемым через Интернет, не разрешено записывать данные на жесткий диск посредством обычных классов ввода-вывода, но они могут использовать изолированное хранилище для хранения параметров пользователя и состояний приложения.

  • Хранение общих компонентов. Компоненты, общие для нескольких приложений, могут использовать изолированное хранилище для обеспечения управляемого доступа к хранилищам данных.

  • Хранение на сервере. Серверные приложения могут использовать изолированные хранилища для представления отдельных хранилищ большому числу пользователей, обращающихся с запросами к приложению. Поскольку изолированное хранилище всегда сегментируется по пользователям, сервер должен имитировать действия пользователя, создающего запрос. В этом случае данные изолируются на основе идентификатора субъекта, который является тем же идентификатором, который используется приложением для того, чтобы различать пользователей.

  • Перемещение. Приложения могут также использовать изолированное хранилище с перемещаемыми профилями пользователей. Это позволяет изолированным хранилищам пользователя перемещаться вместе с его профилем.

Изолированное хранилище не следует использовать в следующих ситуациях:

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

  • Для хранения кода.

  • Для хранения параметров конфигурации и развертывания, которые контролируются администраторами. (настройки пользователя не считаются параметрами конфигурации, т.к. они не управляются администраторами).

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

Заголовок Описание
Типы изоляции Описание различных типов изоляции.
Практическое руководство. Получение хранилищ для изолированного хранения Приводится пример использования класса IsolatedStorageFile для получения хранилища, изолированного по сборке и пользователю.
Как перечислить хранилища изолированного хранения Пример использования метода IsolatedStorageFile.GetEnumerator для вычисления общего размера всех изолированных хранилищ пользователя.
Как удалить хранилища в изолированном хранилище Пример использования метода IsolatedStorageFile.Remove для удаления изолированных хранилищ двумя разными способами.
Практическое руководство. Предупреждение о нехватке места при изолированном хранении Пример измерения оставшегося свободного места в изолированном хранилище.
Практическое руководство. Создание файлов и каталогов в изолированном хранилище Предоставляются примеры создания файлов и каталогов в изолированном хранилище.
Практическое руководство. Поиск существующих файлов и каталогов в изолированном хранилище Пример считывания структуры каталогов и файлов в изолированном хранилище.
Как считывать и записывать файлы в изолированное хранилище Содержит пример записи строки в файл изолированного хранилища и его чтения.
Практическое руководство. Удаление файлов и каталогов из изолированного хранилища Пример удаления файлов и каталогов в изолированном хранилище.
Файловый и потоковый ввод-вывод Объясняется, как можно выполнять синхронный и асинхронный доступ к файлам и потокам данных.

Справочные материалы