Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
CheckBootSpeed - это диагностический пакет на основе скриптов PowerShell, создающий отчет о скорости загрузки Windows 7 ...
Вы когда-нибудь хотели создать установочный диск Windows, который бы автоматически установил систему, не задавая вопросо...
Если после установки Windows XP у вас перестала загружаться Windows Vista или Windows 7, вам необходимо восстановить заг...
Программа подготовки документов и ведения учетных и отчетных данных по командировкам. Используются формы, утвержденные п...
Red Button – это мощная утилита для оптимизации и очистки всех актуальных клиентских версий операционной системы Windows...
OSzone.net Microsoft Разработка приложений .NET Framework Перенос сборки APTCA в .NET Framework 4 RSS

Перенос сборки APTCA в .NET Framework 4

Текущий рейтинг: 0 (проголосовало 0)
 Посетителей: 718 | Просмотров: 2092 (сегодня 0)  Шрифт: - +

В Microsoft .NET Framework 4 модель защиты общеязыковой исполняющей среды (CLR) подверглась некоторым существенным изменениям. Одно из таких изменений — введение транспарентности Level 2 (во многом по аналогии с моделью защиты Silverlight) — скорее всего коснется авторов библиотек AllowPartiallyTrustedCallers (APTCA).

Причина в том, что нижележащая инфраструктура APTCA изменилась в CLR v4. Атрибут APTCA по-прежнему обеспечивает доступ частично доверяемым вызывающим к полностью доверяемым библиотекам, но осуществляется это иначе, и в итоге понадобятся некоторые модификации в коде APTCA-библиотеки.

Заметьте: ссылки на v2 в этой статье относятся к CLR v2, которая содержится во всех версиях .NET Framework от 2.0 до 3.5 SP1.

APTCA до v4

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

Добавление атрибута AllowPartiallyTrustedCallers к подписанной полностью доверяемой библиотеке делает ее доступной частично доверяемому коду за счет удаления неявных запросов связывания (link demands). Соответственно APTCA-библиотеки разрешали управляемый доступ частично доверяемому коду к привилегированным операциям через методы, предоставляемые APTCA. Поэтому вся ответственность за открытие частично доверяемому коду лишь безопасных операций и за защиту любых потенциально опасных операций с помощью явных запросов связывания или требований полных прав доступа возлагалась на авторов APTCA.

APTCA в v4

Атрибут AllowPartiallyTrustedCallers изменен. В v4 он больше не работает с запросами связывания. По сути, самого неявного запроса на связывание, который присутствовал в подписанных библиотеках в v2, больше нет. Вместо этого все полностью доверяемые сборки в v4 по умолчанию имеют уровень SecurityCritical. С другой стороны, все частично доверяемые сборки в v4 автоматически получают уровень SecurityTransparent. Как поясняется в кратком обзоре транспарентности в следующем разделе, SecurityCritical-код нельзя вызывать из SecurityTransparent-кода.

Таким образом, новая система транспарентности в v4 обеспечивает ту же защиту полностью доверяемого кода, что и прежние запросы связывания; из-за автоматического назначения уровней транспарентности SecurityCritical и SecurityTransparent частично доверяемый код не может по умолчанию вызывать полностью доверяемые библиотеки.

Как вы, вероятно, догадались, изменение AllowPartiallyTrustedCallers в v4 относится именно к этому. В v4 он блокирует автоматическое назначение SecurityCritical сборке, к которой он применяется. В этом случае сборка по умолчанию получает уровень SecurityTransparent, но автор APTCA-сборки может при необходимости использовать для конкретных типов и методов атрибуты SecurityCritical и SecuritySafeCritical.

Краткий обзор транспарентности

Суть атрибутов транспарентности вроде SecurityTransparent и SecurityCritical известна читателям, знакомым с моделью защиты Silverlight, так как новая модель транспарентности в v4 очень на нее похожа.

Давайте рассмотрим три основных атрибута траспарентности: SecurityTransparent, SecuritySafeCritical и SecurityCritical.

SecurityTransparent Код, помеченный как SecurityTransparent, безопасен с точки зрения защиты. Он не может выполнять никаких опасных операций, например присваивать разрешения, запускать непроверяемый код или вызывать неуправляемый код. Он также не может напрямую вызывать SecurityCritical-код.

  • Как отмечалось, весь частично доверяемый код принудительно помечается как SecurityTransparent из соображений безопасности. Это также уровень транспарентности для APTCA-библиотек по умолчанию.

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

  • Атрибут SecurityCritical может получить только полностью доверяемый код. И фактически полностью доверяемый код (отличный от APTCA) считается SecurityCritical по умолчанию, чтобы защитить его от транспарентного частично доверяемого кода.

SecuritySafeCritical Этот код выступает в роли моста, который позволяет транспарентному коду вызывать критические методы. SecuritySafeCritical-код имеет те же права, что и SecurityCritical-код, но его можно вызывать из SecurityTransparent-код. Таким образом, крайне важно, чтобы SecuritySafeCritical-код предоставлял нижележащие SecurityCritical-методы, только если это безопасно.

  • Как и SecurityCritical-код, SecuritySafeCritical-код должен быть полностью доверяемым.

На рис. 1 показано взаимодействие между SecurityTransparent-, SecuritySafeCritical- и SecurityCritical-кодом.

*
Рис. Взаимодействие между SecurityTransparent-, SecuritySafeCritical- и SecurityCritical-кодом

Заметьте, что в дополнение к переходам, показанным на схеме, все уровни транспарентности могут обращаться сами к себе и к менее критическому коду (например, SecuritySafeCritical-код может обращаться к SecurityTransparent-коду). Поскольку атрибут AllowPartiallyTrustedCallers по умолчанию превращает всю сборку в SecurityTransparent, автор сборки должен самостоятельно помечать методы, которым нужны привилегированные операции, как SecurityCritical или SecuritySafeCritical. Без этого автор APTCA обнаружит, что его код вызывает исключения MethodAccessExceptions, TypeAccessExceptions и другие ошибки, указывающие на то, что APTCA-библиотека пытается вызывать опасные API из SecurityTransparent-кода.

Это лишь краткое введение к описанию модели; более подробные пояснения см. в документации MSDN и в предыдущей статье из рубрики «CLR с изнанки» по ссылке msdn.microsoft.com/magazine/8e75546c-416a-44e1-8462-e39205fb942a.

Переход с v2 на v4: какие атрибуты нужно применять

Большая часть работы, необходимой для переноса APTCA-сборки v2 в v4 включает определение и применение корректных атрибутов транспарентности к методам, которым это нужно. Ниже поясняется, в каких случаях имеет смысл каждый атрибут.

SecurityTransparent Код, который не выполняет никаких операций, влияющих на безопасность, должен быть SecurityTransparent.

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

Одно из преимуществ транспарентного кода в том, что он безопасен (так как все опасные операции запрещены) и в итоге не требует столь тщательно анализа на предмет безопасности, как SecurityCritical- и особенно SecuritySafeCritical-код. Рекомендуется, чтобы максимально возможное количество кода было именно SecurityTransparent.

Следующие операции в SecurityTransparent-коде запрещены:

  • вызов SecurityCritical-методов;
  • выдача разрешения или набора разрешений;
  • наличие непроверяемого кода;
  • вызов неуправляемого кода;
  • переопределение виртуальных методов уровня SecurityCritical;
  • реализация SecurityCritical-интерфейсов;
  • наследование от любого типа, отличного от SecurityTransparent-типа.

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

Поскольку SecuritySafeCritical позволяет частично доверяемым вызывающим опосредованно обращаться к опасным API, это очень мощный атрибут, который следует применять с большой осторожностью. Важно, чтобы SecuritySafeCritical-код предоставлял свою SecurityCritical-функциональность вызывающему коду только специфическими, безопасными способами. Обычно SecuritySafeCritical-код должен содержать запросы (demands), гарантирующие, что вызывающий код сможет обращаться к определенным ресурсам, которые будет использовать SecuritySafeCritical-код. Также важно, чтобы SecuritySafeCritical-код проверял корректность ввода и вывода (во избежание передачи недопустимых значений и для обеспечения безопасности любой информации, возвращаемой частично доверяемому коду).

Из-за потенциального риска для безопасности рекомендуется, чтобы объем SecuritySafeCritical-кода был минимально возможным.

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

SecurityCritical-код менее опасен, чем SecuritySafeCritical-код, поскольку его нельзя напрямую вызвать из транспарентного (частично доверяемого) кода. Однако этот код может выполнять много операций с высокой степенью защиты, поэтому, чтобы уменьшить потребность в анализе защиты, объем SecurityCritical-кода тоже должен быть минимален.

Универсальное правило таково: любой код, который может быть SecurityTransparent, и должен быть им. Остальной код должен быть SecurityCritical, если только нет реальной необходимости в обращении транспарентного кода к SecurityCritical; в последнем случае такой код должен быть помечен атрибутом SecuritySafeCritical.

Использование SecAnnotate.exe

Чтобы помочь вам с правильным применением атрибутов транспарентности, в .NET Framework SDK включена новая утилита, Security Annotator (SecAnnotate.exe). Эта утилита использует предоставляемый вами двоичный файл (или набор двоичных файлов) и показывает, где и какие атрибуты транспарентности следует применить. Она может оказаться очень полезной при переносе APTCA-библиотеки в v4.

SecAnnotate делает несколько проходов по двоичному файлу, отыскивая методы, которые, согласно правилам CLR, должны быть помечены атрибутом транспарентности. При последующих проходах утилита смотрит, какие атрибуты нужны с учетом модификаций, предложенных после предыдущих проходов. Рассмотрим для примера небольшой фрагмент кода (предполагается, что он взят из APTCA-сборки):

SecAnnotate.exe сразу же распознала бы, что Method2 не может быть транспарентным, поскольку он назначает некоторые разрешения. После первого прохода утилита определила бы, что Method2 должен быть либо SecurityCritical, либо SecuritySafeCritical (причем SecurityCritical предпочтительнее, если только транспарентному коду не нужно обращаться к этому методу).

При первом проходе Method1 был бы пропущен утилитой. Но на втором она отметила бы, что Method1 вызывает Method2, который при первом проходе SecAnnotate предложила сделать SecurityCritical. Из-за этого Method1 тоже должен быть SecurityCritical (или, по усмотрению автора, SecuritySafeCritical). После двух проходов утилита сообщила бы, что оба метода стоит пометить как SecurityCritical.

Разбираемся в выводе SecAnnotate.exe

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

Посмотрите, например, на вывод Security Annotator на рис. 2. аметьте, что под тегом annotations для метода Logging.MethodA есть два элемента: теги SecuritySafeCritical и SecurityCritical. Это означает, что при анализе SecAnnotate рекомендовала для данного метода оба атрибута SecurityCritical и SecuritySafeCritical.

Рис. Вывод Security Annotator

В пояснении к элементу SecurityCritical говорится: так как этот метод вызывает какой-то код, защищенный запросом связывания, он должен быть либо SecurityCritical, либо SecuritySafeCritical. По умолчанию SecAnnotate.exe рекомендует SecurityCritical, потому что он безопаснее. Обратите внимание на номер прохода, равный 1, а это значит, что данное предложение сделано SecAnnotate.exe на основе первого прохода по коду.

В следующей рекомендации — для SecuritySafeCritical — отмечается, что MethodA переопределяет транспарентный базовый метод и поэтому должен быть SecurityTransparent или SecuritySafeCritical (его права доступа должны быть идентичны тем, которые есть у базового метода). Сложив эту информацию с предыдущей рекомендацией, SecAnnotate.exe предлагает пометить MethodA атрибутом SecuritySafeCritical.

Заметьте: pass="2" означает, что данная рекомендация сформирована на основе второго прохода SecAnnotate.exe по коду. Дело в том, что при первом проходе утилита не узнала, что MethodA не может быть транспарентным, а потому не распознала это требование SecuritySafeCritical.

Поскольку рекомендация по SecuritySafeCritical была сделана на втором (более позднем) проходе, правильной следует считать именно ее в данном случае.

Особенности работы SecAnnotate.exe

В тех случаях, когда и SecurityCritical, и SecuritySafeCritical являются корректными атрибутами, Security Annotator сначала предпочитает выбрать любой атрибут, уже присутствующий в коде, а затем SecurityCritical, так как он менее рискованный. Увы, это часто приводит к тому, что код становится безопасным, но не подходящим для запуска в изолированной программной среде («песочнице») из-за блокировки всех точек входа для частично доверяемого кода.

Помните, что SecuritySafeCritical подходит для API, которые вызываются напрямую из транспарентного (частично доверяемого) кода и были проанализированы на безопасность с учетом этого. Так как Security Annotator не знает, какие API рассчитаны на вызов из частично доверяемого кода или являются безопасными в этом отношении, она очень редко помечает их как SecuritySafeCritical. Автор библиотеки должен вручную применять атрибут SecuritySafeCritical к некоторым методам, даже используя Security Annotator.

Поскольку единственное действие, запрещенное в транспарентном коде, может «сплести паутину» во многих блоках кода, помеченных SecurityCritical в результате успешных проходов Security Annotator без замены на атрибут SecuritySafeCritical, лучше запускать SecAnnotate.exe с ключом /p в командной строке. Ключ /p:x (где x — число) указывает Security Annotator выполнять только x проходов. Вот хороший способ применения Security Annotator:

  1. Запустите SecAnnotate.exe /p:1 /d:<путь к сборкам, на которые есть ссылки> <FileName.dll>.
    a. Это добавит атрибуты транспарентности там, где они нужны, но только с однократным проходом. Остановка на данном этапе позволит автору проверить атрибуты вручную.
    b. По умолчанию SecAnnotate.exe ищет зависимости аннотируемой сборки только в GAC. Для других сборок нужно указывать их пути ключом /d в командной строке.
  2. Обновите исходные файлы библиотеки предложенными атрибутами. Но проанализируйте случаи с несколькими возможными атрибутами и решите, какой из них корректен. Иногда правильным атрибутом будет SecuritySafeCritical, несмотря на предпочтение SecurityCritical утилитой SecAnnotate.
  3. Скомпилируйте заново сборки и повторите все с п. 1 без ключа /p:1. Вы могли бы перезапустить программу с ключом /p:1, но не делайте этого — необходимые атрибуты SecuritySafeCritical уже присутствуют после первой итерации п. 2.

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

Идентификация и анализ API с атрибутами SecuritySafeCritical

Как уже отмечалось, SecAnnotate.exe часто рекомендует пометить какой-либо API атрибутом SecurityCritical или SecuritySafeCritical. Ключ к выбору — можно ли данный API безопасно вызывать из частично доверяемого кода. Если API выполняет все проверки, необходимые для того, чтобы гарантировать безопасность вызова нижележащих критических или неуправляемых API (через запросы связывания или контроль ввода и вывода, например), то ему можно присвоить атрибут SecuritySafeCritical, который иногда предпочтителен, поскольку разрешает вызывать данный API транспарентному коду. С другой стороны, если через этот API вредоносный код может каким-нибудь образом получить доступ к защищенным ресурсам, данный API должен быть SecurityCritical.

Важно очень тщательно проанализировать весь SecuritySafeCritical-код на наличие проблем с безопасностью в случае доступа к нему частично доверяемого кода. Хотя объем SecuritySafeCritical- и SecurityCritical-кода должен быть по возможности минимальным, при любом сомнении атрибут SecurityCritical будет более надежным вариантом.

Применение атрибутов транспарентности

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

  • SecurityTransparentAttribute
    SecurityTransparentAttribute — заметьте, что этот атрибут применим только на уровне сборки. А значит, все типы и методы в данной сборке являются транспарентными. Он не нужен на уровне типов или методов, потому что автоматически назначается APTCA-сборкам по умолчанию.
  • SecuritySafeCriticalAttribute
  • SecurityCriticalAttribute

В C# атрибуты применяются так:

Level1 и Level2

Одно из последних замечаний по поводу транспарентности и APTCA. Несмотря на использование атрибута уровня сборки есть возможность задействовать прежнее поведение APTCA v2 вместо нового в v4. Делать это не рекомендуется, так как новая модель надежнее, проще в аудите и является общей для Silverlight и настольной CLR. Тем не менее иногда требуется сохранение совместимости на время переноса кода.

В таких случаях можно применять атрибут SecurityRules, который заставит сборку использовать старые правила v2. Атрибут SecurityRules принимает параметр SecurityRuleSet перечислимого типа. SecurityRuleSet.Level1 указывает на выбор совместимости, а SecurityRuleSet.Level2 — на выбор новой модели, но на самом деле атрибут Level2 не нужен, так как это вариант по умолчанию. Однако он может пригодиться для явного указания того, какой набор правил транспарентности используется в данном коде, и поможет защититься от любых будущих изменений в .NET Framework, касающихся выбора правил по умолчанию.

В C# этот атрибут применяется так:

Распространенные проблемы

Ниже перечислен ряд подводных камней, на которые могут напороться авторы APTCA-библиотек при переходе с v2 на v4.

  • SecAnnotate.exe будет рекомендовать преобразовать запросы LinkDemand в атрибуты SecurityCritical (которые очень похожи на LinkDemand для FullTrust). Однако, если некий тип (а не метод) был защищен с помощью LinkDemand, это вовсе не то же самое, что применение SecurityCritical к этому типу в v4. Лучше применять SecurityCritical ко всем членам типа, так как тогда он будет действовать более похоже на LinkDemand уровня типа в v2.
  • Заметьте, что некоторые LinkDemand с низким уровнем разрешений, ожидаемых частично доверяемым кодом, лучше не преобразовывать в SecurityCritical. Если LinkDemand требует низкого уровня разрешений (например, разрешение на чтение по определенному безопасному пути), лучше удалить этот LinkDemand и заменить его запросом полного доверия (full demand) для того же уровня разрешений. Это позволит частично доверяемому коду по-прежнему вызывать данный API (но такой запрос будет гарантировать, что только частично доверяемый код с достаточно высокими разрешениями преуспеет в вызове).
  • В целом, атрибуты транспарентности уровня типа применимы и к членам модифицируемого ими типа. И самый внешний атрибут переопределяет остальные. Поэтому, например, применение [SecurityCritical] к методу бесполезно, если к типу применен [SecuritySafeCritical]. Как правило, [SecuritySafeCritical] не является полезным атрибутом на уровне типа. Весьма высока вероятность того, что кто-то позднее введет новый член в этот тип, не осознавая, что он является SecuritySafeCritical (из-за атрибута уровня типа), что потенциально может создать брешь в защите.

Хотя атрибуты уровня типа применимы к новым слотовым членам (slot members) модифицируемых ими типов, они неприменимы к переопределенным членам. Убедитесь, что если вы используете атрибуты транспарентности уровня типов, то добавляете атрибуты к переопределенным членам (когда это необходимо).

Пример переноса кода

На рис. 3 приведена простая (и незаконченная) библиотека протоколирования, написанная в расчете на v2.

Рис. APTCA-библиотека в v2

Та же библиотека, показанная на рис. 4, перенесена в v4 с комментариями (выделенными курсивом), в которых поясняются изменения.

Рис. APTCA-библиотека в v4

Синхронизация систем защиты CLR и Silverlight CoreCLR

Хотя совмещение APTCA и транспарентности в v4 может показаться делом сложным, оно в конечном счете обеспечит четкую и эффективную защиту важных системных ресурсов от частично доверяемого кода. Более того, это изменение выравнивает между собой системы защиты в настольной CLR и в Silverlight CoreCLR.

Такие утилиты из SDK, как SecAnnotate.exe и FxCop (которая может проверять корректность транспарентности), упрощают перенос кода. APTCA-сборки v4 намного легче в аудите безопасности: надо лишь внимательно проанализировать API с атрибутами SecuritySafeCritical (и SecurityCritical-вызовы, которые они делают).

Так как транспарентный код зачастую составляет более 80–90% сборки, это сильно упрощает аудит. Читатели, заинтересованные в более глубоком рассмотрении транспарентности, найдут полное описание в документации MSDN.

using System;
using System.IO;
using System.Security;
using System.Security.Permissions;

// This assembly is meant to be representative of a simple v2 APTCA assembly
// It has some dangerous code protected with demands/link demands
// It exposes some dangerous code in a controlled way with an assert

[assembly: AllowPartiallyTrustedCallers]
public class Logging
{
    private string logLocation = @"C:\temp\firstfoo.txt";

    // This API can be transparent because it does nothing dangerous.
    // Transparent APIs need no attributes because it is the default behavior of a v4
    // APTCA assembly
    public virtual string Usage()
    {
        return "This is a helpful string";
    }

    // Note that transparency attributes do not go directly on properties.
    // Instead, they go on the getters and setters (even if the getter and setter
    // get the same attributes)
    public virtual string LogLocation
    {
        get
        {
            return logLocation;
        }

        // This API is made critical because it sets sensitive data (the path to write to)
        // which partial trust code should not be able to do.
        [SecurityCritical]
        // The previous LinkDemand is removed as the SecurityCritical attribute replaces it
	//[FileIOPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
        set
        {
            logLocation = value;
        }
    }

    // This API accesses a critical member (LogLocation) and, therefore, cannot be transparent
    // However, the access is done in a limited, safe way and we expect transparent code
    // should be able to call this API. Therefore, it is SecuritySafeCritical
    [SecuritySafeCritical]
    public virtual void SetLogLocation(int index)
    {
        switch (index)
        {
            case 1:
                LogLocation = @"C:\temp\foo.txt";
                break;
            case 2:
                LogLocation = @"D:\temp\foo.txt";
                break;
            case 3:
                LogLocation = @"D:\repro\temp\foo.txt";
                break;
            default:
                break;
        }
    }

    // This API is potentially dangerous; it asserts which means it can’t be transparent
    // Because setting LogLocation is protected, however, partial trust code can safely
    // call this API. In fact, it is intended that it is safe for partial trust code
    // to call this method. Therefore, it is SecuritySafeCritical
    [SecuritySafeCritical]
    public virtual void DeleteLog()
    {
        FileIOPermission fp = new FileIOPermission(FileIOPermissionAccess.AllAccess, LogLocation);
        fp.Assert();
        if (File.Exists(LogLocation)) { File.Delete(LogLocation); }
        SecurityPermission.RevertAll();
    }

    // TODO : Put other APIs (creating log, writing to log, etc) here
}

public class OtherLogging : Logging
{
    // The logic for attributing this method is complicated and it is an example of when
    // SecAnnotate.exe can be very helpful. This API cannot be transparent because it
    // calls a critical member (LogLocation). However, because it overrides a transparent
    // method (Usage) it cannot be critical. Therefore, the only possible annotation here
    // is SecuritySafeCritical and it is the author’s responsibility to make sure that
    // a malicious caller cannot abuse that access.
    [SecuritySafeCritical]
    public override string Usage()
    {
        LogLocation = null;
        return "This is a different useful string";
    }

    // TODO : Put other APIs (creating log, writing to log, etc) here
}
using System;
using System.IO;
using System.Security;
using System.Security.Permissions;

// This assembly is meant to be representative of a simple v2 APTCA assembly
// It has some dangerous code protected with demands/link demands
// It exposes some dangerous code in a controlled way with an assert

[assembly: AllowPartiallyTrustedCallers]
public class Logging
{
    private string logLocation = @"C:\temp\firstfoo.txt";

    public virtual string Usage()
    {
        return "This is a helpful string";
    }

    public virtual string LogLocation
    {
        get
        {
            return logLocation;
        }

        [FileIOPermissionAttribute(SecurityAction.LinkDemand, Unrestricted=true)]
        set
        {
            logLocation = value;
        }
    }

    public virtual void SetLogLocation(int index)
    {
        switch (index)
        {
            case 1:
                LogLocation = @"C:\temp\foo.txt";
                break;
            case 2:
                LogLocation = @"D:\temp\foo.txt";
                break;
            case 3:
                LogLocation = @"D:\repro\temp\foo.txt";
                break;
            default:
                break;
        }
    }


    public virtual void DeleteLog()
    {
        FileIOPermission fp = new FileIOPermission(FileIOPermissionAccess.AllAccess, LogLocation);
        fp.Assert();
        if (File.Exists(LogLocation)) { File.Delete(LogLocation); }
        SecurityPermission.RevertAll();
    }

    // TODO : Put other APIs (creating log, writing to log, etc) here
}

public class OtherLogging : Logging
{
    public override string Usage()
    {
        LogLocation = null;
        return "This is a different useful string";
    }

    // TODO : Put other APIs (creating log, writing to log, etc) here
}
[assembly:SecurityRules(SecurityRuleSet.Level1)]
[SecurityCritical]
public static void Method1()
{ /* Do something potentially dangerous*/ }

[SecuritySafeCritical]
public static void Method2()
{ /* Do something potentially dangerous in a safe way that can be called from partial trust */ }
<requiredAnnotations>
    <assembly name="Logging">
      <type name="Logging">
        <method name="MethodA()">
          <annotations>
            <safeCritical>
              <rule name="MethodsMustOverrideWithConsistentTransparency">
                <reason pass="2" sourceFile="d:\repro\aptca\logging.cs" sourceLine="67">Critical method Logging.MethodA()’ is overriding transparent or safe critical method ‘Logging.MethodA()’ in violation of method override rules.  Logging.MethodA()’ must become transparent or safe-critical in order to override a transparent or safe-critical virtual method or implement a transparent or safe-critical interface method.</reason>
              </rule>
            </safeCritical>
            <critical>
              <rule name="TransparentMethodsMustNotSatisfyLinkDemands">
                <reason pass="1" sourceFile="d:\repro\aptca\logging.cs" sourceLine="68">Security transparent method Logging.MethodA()’ satisfies a LinkDemand for ‘FileIOPermissionAttribute’ on method ‘Logging.set_LogLocation(System.String)’.  Logging.MethodA()’ should become critical or safe-critical in order to call ‘Logging.set_LogLocation(System.String)’.</reason>
              </rule>
            </critical>
          </annotations>
        </method>
      </type>
    </assembly>
  </requiredAnnotations>
static void Method1()
{
      Console.WriteLine("In method 1!");
      Method2();
}

static void Method2()
{
      PermissionSet ft = new PermissionSet(PermissionState.Unrestricted);
      ft.Assert();
      DangerousAPI();
      PermissionSet.RevertAssert();
}
Автор: Майк Роусос  •  Иcточник: Журнал MSDN  •  Опубликована: 17.01.2011
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER


Оценить статью:
Вверх
Комментарии посетителей
Комментарии отключены. С вопросами по статьям обращайтесь в форум.