CLR с изнанки

Исследование модели защиты в .NET Framework 4

Эндрю Дей

В .NET Framework 4 внесено много обновлений в .NET-модель безопасности, которые упрощают хостинг, защиту и предоставление сервисов частично доверяемому коду. Мы полностью пересмотрели сложную систему Code Access Security (CAS) (разграничение прав доступа кода), которая была мощной, но очень трудной в использовании. Мы также усовершенствовали модель Security Transparency, внеся в нее ряд новинок из Silverlight (об этом я писал в статье за октябрь, см. по ссылке msdn.microsoft.com/magazine/cc765416.aspx) в области принудительного применения системы безопасности для инфраструктуры рабочих столов. Наконец, мы ввели некоторые новые средства, которые дают разработчикам хостов и библиотек больше гибкости в том, как они предоставляют свои сервисы. Благодаря этим изменениям в .NET Framework 4 появилась более простая и совершенная модель защиты, которая облегчает хостам и библиотекам изолирование кода в «песочнице», а библиотекам позволяет безопасно предоставлять сервисы.

Базовые сведения о защите в .NET Framework

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

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

  • Политика (policy) Политика безопасности определяет, какие разрешения следует назначить конкретной недоверяемой сборке или приложению. В управляемом коде есть объекты Evidence, которые сопоставляются с конкретным кодом и позволяют описывать, откуда он был загружен, кто опубликовал его и др. Evidence можно использовать для определения соответствующих разрешений; результат называют набором выданных разрешений (permission grant set). В .NET Framework политика CAS традиционно применялась как механизм уровня компьютера. Я уже упоминал, что политика CAS была полностью пересмотрена для обеспечения большей гибкости хостов в определении собственной политики безопасности.
  • Изолирование (sandboxing) Изолирование — собственно процесс ограничения разрешений сборок или приложений заданным набором. Предпочтительный способ изолирования — создание изолирующего домена приложения, содержащего набор выданных разрешений для загруженных сборок и список исключений для сборок конкретных библиотек (они получают полное доверие). В .NET Framework 4 частично доверяемый код всегда изолируется именно таким способом.
  • Введение ограничений в действие (enforcement) Это механизм, не позволяющий недоверяемому коду выйти за рамки своей «песочницы». Правильное использование API этого механизма не дает недоверяемой сборке просто вызвать API из другой сборки с более высоким уровнем доверия и тем самым повысить уровень своих прав. Он также позволяет разработчикам хостов и библиотек обеспечивать контролируемый, ограниченный доступ к функциональности повышения уровня прав и предоставлять необходимые сервисы частично доверяемому коду. Модель Level 2 Security Transparency значительно упрощает эту задачу.

Модель защиты .NET всегда имела особое значение для разработчиков хостов и библиотек (а хосты и библиотеки часто идут рука об руку). Примеры использования модели защиты .NET — ASP.NET и SQL CLR, которые обеспечивают хостинг управляемого кода в контролируемых средах и ограниченных контекстах. Когда подобному хосту нужно загрузить частично доверяемую сборку, он создает изолированный домен приложения с соответствующим набором разрешений. После этого сборка загружается в изолированный домен. Хост предоставляет библиотечные API, которые являются полностью доверяемыми, но их можно вызывать из размещаемого кода. Соответствующие библиотеки тоже загружаются в изолированный домен, но явно включаются в список исключений, о котором я уже упоминал. В обеспечении жестко контролируемого доступа к их функциям с более высоким уровнем разрешений они полагаются на механизмы введения ограничений в действие, существующие в .NET Framework.

Для большинства разработчиков управляемых приложений все это магия, которая творится на уровне инфраструктуры, — даже тем, кто пишет код, рассчитанный на выполнение в изолированной программной среде, незачем знать все детали того, как работает модель защиты. Инфраструктура гарантирует, что код, выполняемый в изолированной среде, ограничен использованием API и возможностей, предоставляемых хостом. Модель защиты .NET и CAS уже давно являются полем деятельности корпоративных администраторов, а также разработчиков хостов и библиотек; вот для них мы и старались.

Политика

Политика CAS предоставлялась с момента появления .NET Framework и позволяла администраторам компьютеров и корпоративным администраторам тонко настраивать параметры, по которым исполняющая среда рассматривает код как доверяемый или недоверяемый. Хотя политика CAS была мощным средством и обеспечивала очень тонкое управление, ее было крайне трудно правильно настроить, и она могла больше мешать, чем помогать. Администраторы компьютеров могли лишать некоторые приложения необходимых им разрешений (см. также раздел «Изолирование»), и многие удивлялись, почему это их приложения вдруг переставали работать, как только они размещали их на общем сетевом ресурсе. Более того, настройки политики CAS не переносились из одной версии исполняющей среды в другую, поэтому для использования нестандартной политики CAS, настроенной кем-то в .NET Framework 1.1, ее приходилось вручную переделывать под .NET Framework 2.0.

Политику безопасности можно разделить на два вида: для размещаемого кода (hosted code) и для компьютеров или предприятия. В отношении политики для компьютеров группа Common Language Runtime Security решила, что исполняющая среда не годится для управления этой политикой, так как неуправляемый код не подчиняется ее ограничениям. Если возможность для хостов определять, что дозволено размещаемому в них коду, имеет смысл, то автономные исполняемые EXE-файлы, которые можно просто запустить (в том числе из командной строки), должны вести себя как и их неуправляемые аналоги (тем более что на взгляд пользователей они выглядят идентично).

Правильнее размещать глобальную политику безопасности на уровне операционной системы, где такая политика будет в равной мере действовать как на управляемый, так и на неуправляемый код. Поэтому мы призываем администраторов компьютеров выбирать решения наподобие Windows Software Restriction Policies и по умолчанию отключать обработку политики CAS на уровне компьютеров. В случае размещаемого кода политика безопасности по-прежнему играет очень важную роль в мире управляемого кода. Такой политикой теперь легко управлять, так как она больше не пересекается с произвольной политикой уровня компьютера.

Что это значит для вас

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

Для многих приложений эти изменения пройдут незамеченными. Но остальные приложения могут столкнуться с двумя проблемами. Первая состоит в том, что некоторые API, связанные с политикой CAS, исключены, причем это относится главным образом к тем из них, которые загружают сборки (поэтому, если вы выполняете такие операции, читайте дальше). Вторая проблема затрагивает меньший круг разработчиков (в основном тех, кто создает хосты) и заключается в том, что гетерогенные домены приложения (см. раздел «Изолирование») по умолчанию недоступны.

Но я ничего из перечисленного не делаю! Как мне добиться корректной работы?

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

This method [explicitly/implicitly] uses CAS policy, which has been obsoleted by the .NET Framework. In order to enable CAS policy for compatibility reasons, please use the NetFx40_LegacySecurityPolicy configuration switch. Please see [link to MSDN documentation] for more information.

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

<configuration>
   <runtime>
      <!-- enables legacy CAS policy for this process -->
      <NetFx40_LegacySecurityPolicy enabled="true" />
   </runtime>
</configuration>

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

API, затронутые изменениями

Такие API можно разделить на две группы: явно использующие политику CAS и делающие это неявно. В первом случае все очевидно:эти методы обычно находятся в классе System.Security.Policy.SecurityManager и выглядят наподобие SecurityManager.ResolvePolicy. API, явно использующие политику CAS, напрямую вызывают или изменяют параметры политики CAS уровня компьютера, и все они были изъяты.

Второй случай менее очевиден:эти API, как правило, загружают сборки или создают домены приложения с использованием признака (evidence). Политика CAS разрешается на основе этого признака, и сборка загружается с полученным в итоге набором разрешений. Так как по умолчанию политика CAS отключена, бессмысленно пытаться разрешать ее по признаку. Пример такого API — метод Assembly.Load(AssemblyName assemblyRef, Evidence assemblySecurity).

Такой API может быть вызван по двум причинам.

  1. Изолирование Возможно, вам известно, что вызов перегруженной версии Assembly.Load, которая принимает признак зоны из Интернета, приводит к тому, что сборка загружается с набором разрешений для зоны Интернета (если, конечно, администратор не изменил сопоставление этого признака для данной машины или пользователя!).
  2. Другие параметры в перегруженной версии Не исключено, что вам просто понадобился параметр, существующий только в этой перегруженной версии. Тогда в параметре признака вы могли просто передать null или Assembly.GetExecutingAssembly().Evidence.

Если вы пытались добиться изолирования, то в разделе «Изолирование» описывается, как создать изолированный домен приложения, ограниченный набором разрешений зоны Интернета. Вашу сборку можно было бы загружать в этот домен, и она гарантированно получала бы задуманный вами набор разрешений (т. е. этот процесс не зависел бы от прихотей администратора).

Для второго случая мы добавили перегруженные версии к каждому API, предоставляющие все необходимые параметры, но не принимающие параметр признака. Так что весь перенос приложения в этом случае заключается в простом удалении аргумента признака из ваших вызовов. (Заметьте, что передача null в Evidence в устаревшие API по-прежнему возможна, так как не требует обработки политики CAS.)

При попытке загрузки сборки с удаленного ресурса вызовом Assembly.LoadFrom("http://...") генерируется исключение FileLoadException, если только вы не установили следующий конфигурационный параметр. Так было сделано потому, что раньше этот вызов помещал сборку в изолированную программную среду. А теперь в отсутствие политики CAS она неявно получила бы полное доверие!

<configuration>
   <runtime>
      <!-- WARNING: will load assemblies from remote locations as fully
         trusted! -->
      <loadFromRemoteSources enabled="true" />
   </runtime>
</configuration>

Другой способ, не требующий включения этого конфигурационного параметра для всего процесса, — использование нового метода Assembly.UnsafeLoadFrom, который работает так же, как и LoadFrom с включенным параметром loadFromRemoteSources. Это удобно, если вы хотите просто разрешить удаленные загрузки в определенных местах или если вы не являетесь владельцем основного приложения.

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

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

Через политику безопасности хоста мы можем определить корректный набор разрешений, который нужно выдать частично доверяемой сборке. И теперь нам нужен простой, эффективный способ загрузки этой сборки в среду, ограниченную этим набором разрешений. Для этого и предназначено изолирование (sandboxing), особенно с использованием простой перегруженной версии CreateDomain, рассчитанной на создание изолированной среды.

Изолирование в прошлом

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

При использовании этой модели возникало несколько проблем.

  • Набор разрешений, выдаваемый сборке, зависит от политики CAS, так как при вычислении конечного набора разрешений учитываются несколько пересекающихся уровней политики. Следовательно, в итоге может быть получено меньше разрешений, чем задумывалось изначально.
  • По аналогии с предыдущим пунктом оценка признаков сборки выполняется политикой CAS, которая может отличаться для разных компьютеров, пользователей и даже версий исполняющей среды (параметры политики CAS не переносятся в более новые версии исполняющей среды). А значит, не всегда очевидно, какой именно набор разрешений получит сборка.
  • Частично доверяемые сборки обычно не рассматриваются на предмет ужесточения защиты (security hardening), что делает сборки со «средним доверием» уязвимыми перед сборками с «более низкими уровнями доверия». Эти сборки свободно вызывают друг друга, и при наличии множества таких сборок безопасность может пострадать. Кто может поручиться, что все комбинации вызовов от сборок с разными уровнями доверия будут безопасны?

В связи с этими проблемами мы ввели концепцию гомогенного домена приложения (homogeneous application domain), который содержит только два набора разрешений (частичное и полное доверие), полностью предсказуем и крайне прост в создании. О том, как создавать такие домены, я расскажу позже.

Другим популярным механизмом изолирования было использование PermitOnly и Deny — модификаторов прохода по стеку (stack walk modifiers), которые соответственно перечисляют специфические разрешения (и ничего больше) и отключают их. Вроде бы очень удобно заявить:«данный API могут вызывать лишь те, у кого есть разрешения x и y» или «отклонять все разрешения кода, пытающегося вызвать данный API». Однако эти модификаторы на самом деле не изменяли набор разрешений конкретной сборки, а значит, их можно было обойти*, так как они просто перехватывали запросы (demands)*. Пример приведен на рис. 1.

Рис. 1 Стек вызовов, отражающий попытку изолирования с помощью Deny

Без Assert требование попадает на Deny, и проход по стеку завершается. Но, когда Assert активен, попадание на Deny никогда не происходит, так как Untrusted отклонил запрос. (Заметьте: стек вызовов растет в сторону нижних адресов памяти. API в таблице не представляют реальные API в инфраструктуре.) По этой причине Deny в .NET Framework 4 был изъят — его использование всегда создавало брешь в защите, а PermitOnly оставлен, так как его можно применять в нескольких пограничных случаях, но в целом рекомендуется обходиться без него.

Изолирование сегодня

Единица изоляции в .NET Framework — домен приложения (application domain). Каждый частично доверяемый домен приложения имеет единственный набор разрешений, выдаваемый всем сборкам, которые загружаются в этот домен (кроме явно указанных в списке исключений или загружаемых из GAC). Создать этот домен очень легко — .NET Framework предоставляет простой API изолирования, принимающий все, что нужно для решения этой задачи:

AppDomain.CreateDomain( string friendlyName,
 
                        Evidence securityInfo,
                        
                        AppDomainSetup info,
                        
                        PermissionSet grantSet,
                        
                        params StrongName[] fullTrustAssemblies);

Вот что представляют собой эти параметры:

  • friendlyName — описательное имя домена приложения;
  • securityInfo — признак (evidence), сопоставляемый с доменом приложения. Он используется не для разрешения политики CAS, а для хранения такой информации, как сведения об издателе;
  • info — инициализирующая информация для домена приложения. Она должна включать, как минимум, ApplicationBase, представляющий хранилище, где находятся частично доверяемые сборки;
  • grantSet — набор разрешений для всех загружаемых в этот домен сборок, кроме перечисленных в списке полного доверия или загружаемых из GAC;
  • fullTrustAssemblies — список полностью доверяемых сборок с полными именами.

Создав домен, вы можете вызвать метод AppDomain.CreateInstanceAndUnwrap в MarshalByRefObject своей частично доверяемой сборки, а затем вызвать ее входную точку для запуска, как показано на рис. 2.

Рис.2 Изолированная среда для выполнения частично доверяемого кода

PermissionSet permset = new PermissionSet(PermissionState.None);
ps.AddPermission(new SecurityPermission(
   SecurityPermissionFlag.Execution));
AppDomainSetup ptInfo = new AppDomainSetup();
ptInfo.ApplicationBase = ptAssemblyStore;
 
AppDomain sandboxedDomain = AppDomain.CreateDomain(
   "Sandbox",
   AppDomain.CurrentDomain.Evidence,
   ptInfo,
   permset);
 
// assume HarnessType is in the GAC and a MarshalByRef object

HarnessType ht = sandboxedDomain.CreateInstanceAndUnwrap(
   typeof(HarnessType).Assembly.FullName,
   typeof(HarnessType).FullName)
   as HarnessType;
 
ht.LoadPTEntryPoint();

Вот и все! Несколько строк кода, и мы получаем изолированную программную среду для выполнения частично доверяемого кода.

Этот CreateDomain на самом деле был добавлен еще в .NET Framework 2.0, так что он отнюдь не нов. Однако теперь это единственный поддерживаемый способ изоляции кода. Как видите, набор разрешений передается напрямую, поэтому при загрузке сборок в этот домен нет нужды анализировать признаки; вы точно знаете, какие разрешения получит каждая загружаемая сборка. Более того, вы используете настоящую изолированную среду, содержащую частично доверяемый код, а это очень сильно помогает в корректной настройке защиты.

Введение ограничений в действие

К этому моменту мы получили соответствующий набор разрешений от частично доверяемой сборки и загрузили ее в подходящую изолированную среду («песочницу»). Здорово! А как быть, если нам вдруг понадобится предоставить частично доверяемому коду некую функциональность, требующую более высоких прав доступа? Например, я не хотел бы выдавать приложению из Интернета полные права доступа к файловой системе, но был бы не против, если бы оно что-то читало и записывало в известной временной папке.

Те, кто читал прошлогоднюю статью по безопасности Silverlight (msdn.microsoft.com/magazine/cc765416.aspx), точно знают, как эта проблема решена на платформе Silverlight:через модель Security Transparency, которая четко делит код на три категории. С радостью сообщаю, что эти достижения в Silverlight теперь есть и в .NET Framework 4. А значит, преимущества более простой модели библиотек на платформе Silverlight стали доступны и сторонним разработчикам частично доверяемых библиотек. Но, прежде чем рассматривать детали и обсуждать другие усовершенствования в этой сфере, давайте обсудим наши прежние основные механизмы введения ограничений в действия.

Введение ограничений в действие в прошлом

В прошлом году я упоминал, что на самом деле Security Transparency была введена в .NET Framework 2.0, но служила в основном в качестве механизма аудита, а не введения ограничений в действие (новая модель Security Transparency рассчитана на обе задачи). В более старой модели — Level 1 Security Transparency — попытки нарушения защиты не проявлялись как четкие ошибки, многие из них (например вызов неуправляемого кода через P/Invoke) приводили к запросам разрешений. При наличии UnmanagedCode в наборе разрешений ваша транспарентная сборка все равно могла делать то, что она делала и тем самым нарушать правила транспарентности в процессе. Более того, проверки транспарентности прекращались на границе сборки, что еще больше уменьшало ее эффективность как механизма введения ограничений в действие.

Реальное введение ограничений в действие было реализовано в .NET Framework 2.0 в виде LinkDemands — проверок на этапе JIT-компиляции, которые контролировали наличие требуемого разрешения в наборе разрешений вызывающей сборки. И все бы хорошо, но эта модель фактически требовала от разработчиков библиотек использовать два разных механизма для аудита и введения ограничений в действие, что явно было излишеством. Модель Silverlight, которая объединила и упростила эти две концепции, была логичным усовершенствованием и теперь называется Level 2 Security Transparency.

Level 2 Security Transparency

Level 2 Security Transparency — механизм введения ограничений в действие, разделяющий код на две категории:безопасно выполняемый в средах с низким уровнем доверия и тот, выполнять который в таких средах, опасно.Если в двух словах, то он создает барьер между кодом, который может выполнять операции, критичные для безопасности (Critical), например файловые операции, и кодом, который этого не может (Transparent).

Модель Security Transparency делит код на три категории: Transparent, Safe Critical и Critical.. Эти категории показаны на (рис. 3). (Примечание: темно-серые стрелки представляют разрешенные вызовы, а светло-серые — запрещенные вызовы.Также допустимы замкнутые циклы (self-loops), но на иллюстрации не показаны.)


Рис. 3 Модель Security Transparency

На типичные настольные приложения модель Level 2 Transparency не оказывает видимого влияния — код без каких-либо аннотаций защиты (security annotations), работающий вне изолированной программной среды, относится к категории Critical, а потому не связан никакими ограничениями. Однако, поскольку это Critical-код, он недосягаем частично доверяемому коду. Следовательно, разработчикам, не использующим частично доверяемый код, не придется заботиться о предоставлении своей функциональности такому коду.

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

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

Атрибуты Security Transparency и их влияние описаны на рис. 4. Учтите, что атрибут с самым высоким уровнем разрешений (highest-scoped attribute) применяется ко всем API, вводимым под ним, независимо от аннотаций этих API. AllowPartiallyTrustedCallers отличается в том плане, что он выдает более низкоуровневые атрибуты. (Примечание: в таблице описываются атрибуты и их поведение на уровнях сборки, типа и члена. Атрибуты применяются только к введенным API, т. е. подклассы и переопределенные версии подчиняются правилам наследования и могут быть на других уровнях Transparency.)

Рис. 4 Атрибуты Security Transparency и их влияние

Те, кто помнят статью за прошлый октябрь, вероятно, заметят, что атрибуты работают примерно как и в Silverlight. Возможно, вы также помните, что с разными типами кода были сопоставлены специфические правила наследования. Они действуют и в настольных приложениях. Подробнее о правилах наследования и других аспектах Level 2 Transparency см. в статье «Security in Silverlight 2» (msdn.microsoft.com/magazine/cc765416.aspx).

Условный AllowPartiallyTrustedCallers

Атрибут AllowPartiallyTrustedCallers (APTCA) указывает, что сборка является библиотекой, которая может предоставлять частично доверяемому коду чувствительную для безопасности функциональность. Сборки библиотек APTCA часто пишутся в комбинации с хостами, так как хостам обычно требуется предоставлять специфическую функциональность размещаемым средам. Один из ярких примеров тому — ASP.NET, которая предоставляет доступ к пространству имен System.Web размещаемому коду, который может иметь разные уровни доверия.

Однако присваивание сборке атрибута APTCA означает, что она доступна частично доверяемому коду в любом хосте, который загрузит ее; это может создать проблемы, если автор сборки не знает, как она поведет себя в разных хостах. Поэтому разработчики хостов иногда предпочитают, чтобы их библиотеки были доступны частично доверяемому коду только при загрузке в собственные домены. Именно так и делается в ASP.NET, а в ранних версиях приходилось использовать LinkDemands для получения специальных разрешений для их API. Это работает, но заставляет любого, кто создает код, опирающийся на эти библиотеки, удовлетворять соответствующий запрос LinkDemand, чтобы сборки, расположенные выше по стеку, не стали транспарентными.

Для решения этой проблемы мы ввели Conditional APTCA, который позволяет библиотекам предоставлять API частично доверяемым вызывающим только в поддерживающем такой вариант хосте (через список).

Ниже перечислены специфические роли хоста и библиотеки.

  • Библиотека просто дополняет атрибут AllowPartiallyTrustedCallers параметром — перечислением PartialTrustVisibilityLevel, например:
[assembly: AllowPartiallyTrustedCallers(PartialTrustVisibilityLevel= PartialTrustVisibilityLevel.NotVisibleByDefault)]
  • Этот атрибут главным образом сообщает, что эту библиотеку нельзя вызывать из частично доверяемого кода, если только он не включен в список разрешений хоста (allow list). Значение VisibleToAllHosts позволит вызывать библиотеку из частично доверяемого кода во всех хостах.

  • Хост указывает нужные сборки с частичным доверием для каждого домена приложения отдельно через список разрешений. Этот список обычно заполняется через конфигурационный файл, предоставляемый хостом. Важно помнить, что добавлять в этот список сборки с безусловным APTCA (unconditional APTCA) вроде базовых библиотек инфраструктуры не требуется.Также учтите, что, если вы поддерживаете сборку Conditional APTCA, то должны разрешить и ее транзитивное замыкание (transitive closure) зависимых сборок Conditional APTCA. Иначе вы можете столкнуться со странным поведением, когда ваша исходная сборка попытается вызывать API, которые должны быть доступны, но на самом деле — нет.

Обеспечивать безопасность станет легче

Многое изменилось в модели защиты для .NET Framework 4. Политика CAS по умолчанию отключена, что возлагает все решения по политике безопасности на хост и уравнивает в правах неразмещенные управляемые EXE-файлы с неуправляемыми EXE-файлами. Отключение политики CAS также влечет за собой отключение гетерогенных доменов приложения, что наконец-то превращает перегруженную версию CreateDomain в основной механизм создания изолированных сред для частично доверяемых сборок. Улучшения в модели Security Transparency для Silverlight, описанные в статье за прошлый октябрь, теперь доступны и настольным приложениям.

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

Эндрю Дей (Andrew Dai) — менеджер программ в группе CLR Security. За более подробными сведениями о том, как пользоваться средствами, упомянутыми в этой статье, пожалуйста, обращайтесь к блогам группы CLR (blogs.msdn.com/clrteam) и Шона Фаркаса (Shawn Farkas) (blogs.msdn.com/shawnfa).Выражаю благодарность следующим экспертам, которые рецензировали эту статью:Cristian Eigel, Shawn Farkas, Joshua Goodman, Mike Rousos и Mueez Siddiqui.