WWW.BOOK.LIB-I.RU
БЕСПЛАТНАЯ  ИНТЕРНЕТ  БИБЛИОТЕКА - Электронные ресурсы
 


Pages:     | 1 | 2 || 4 | 5 |

«том 4 альманах програ ста Тематический сборник материалов MSDN Library и IN/ISDN' Magazine Microsoft Безопасность в.NET Шифрование Защита кода и данных Н.РШШР Е альманах программиста ...»

-- [ Страница 3 ] --

Выдача разрешений Защита на основе признаков основана на предположении, что высокий уровень доверия (с широкими полномочиями) присваивается лишь коду, заслуживающему доверия, а злонамеренный код является мало доверяемым или вообще не имеет разрешений. В политике по умолчанию в.NET Framework разрешения выдаются на основе зон (так, как они определены в Microsoft Internet Explorer). Ниже приведено упрощенное описание этой политики по умолчанию.

• Зона локального компьютера (например, c:\app.exe) является полностью доверяемой. Предполагается, что пользователи помещают на свой Принципы безопасного кодирования для.NET Framework 149 компьютер только код, которому они доверяют, и что большинство пользователей не собираются разбивать свой жесткий диск на области с разной степенью доверия. По существу, этот код может делать все что угодно, поэтому от злонамеренного кода, находящегося в этой зоне, никакой защиты нет.

• Зона Интернета (например, http://www.microsoft.com/). Коду из этой зоны предоставляется очень ограниченный набор разрешений, который неопасно предоставить даже злонамеренному коду. Обычно этому коду нельзя доверять, поэтому его можно безопасно выполнять только с очень узкими разрешениями, с которыми он не сумеет нанести ущерб:

• WebPermission — доступ к серверу сайта, с которого получен код;

• FileDialogPermission — доступ только к файлам, специально указанным пользователем;

• IsolatedStorageFilePermission — постоянное хранилище, ограниченное пределами Web-сайта;

• UlPermission — возможность записи информации в окно пользовательского интерфейса.

• Зона интрасети (например \\UNC\share). Код из этой зоны выполняется с чуть большими разрешениями, чем код из Интернета, но среди них' все равно нет таких, которые предоставляли бы широкие полномочия:

• FilelOPermission — доступ только для чтения к файлам каталога, из которого загружен код;

• WebPermission — доступ к серверу, с которого загружен код;

• DNSPermission — допускается разрешение DNS-имен в IP-адреса;

• FileDialogPermission — доступ только к файлам, специально указанным пользователем;

• Isolated StorageFilePermission — постоянное хранилище (с меньшими ограничениями);

• UlPermission — код может свободно использовать собственные окна верхнего уровня.

.'

• Зона ограниченных сайтов, код из которой выполняется только с минимальными разрешениями.

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

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

Опасные разрешения

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





К опасным разрешениям относятся:

• Security Permission:

• U n managed Code — позволяет управляемому коду вызывать неуправляемый код, что зачастую весьма опасно;

• Skip Verification — код может делать что угодно без всякой верификации;

• ControlEvidence — управление признаками позволяет обмануть систему защиты;

• ControlPolicy — возможность изменять политику безопасности позволяет отключить защиту;

• SerializationFormatter — за счет сериализации можно обойти управление доступом (см. раздел по сериализации);

• ControlPrincipal — возможность указывать текущего пользователя позволяет обходить защиту на основе ролей;

• ControlThread — возможность манипуляций с потоками опасна, так как с ними связано состояние защиты;

• ReflectionPermission:

• MemberAccess — позволяет отключать механизм управления доступом (становится возможным использование закрытых членов).

Защита и конкуренция

Еще одна проблема обеспечения безопасности — возникновение дыр в системе защиты из-за конкуренции (race conditions). Конкуренция проявляется в нескольких ситуациях. В следующих подразделах рассказывается о некоторых типичных ловушках, которых должны избегать разработчики.

Принципы безопасного кодирования для.NET Framework 151 Конкуренция в методе Dispose

Если метод Dispose класса не синхронизирован, код очистки в этом методе может быть выполнен более одного раза. Рассмотрим такой код:

–  –  –

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

Конкуренция в конструкторах

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

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

–  –  –

:

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

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

Конкуренция при подготовке объекта к уничтожению Еще один источник конкуренции — объекты, которые ссылаются на статический или неуправляемый ресурс и освобождаются через метод Finalize (готовящий объект к уничтожению). Если несколько объектов совместно используют ресурс, с которым выполняются какие-то операции в управляемом методе Finalize класса, то объекты должны синхронизировать доступ к этому ресурсу.

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

Генерация кода «на лету»

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

Вы всегда должны точно знать, какой код генерируется. Это значит, что нужно строго контролировать любые значения, получаемые от пользователя: строки в кавычках (их следует избегать, так как в них можно помещать непредсказуемые элементы кода), идентификаторы (проверяйте их на допустимость) и любые другие данные. Идентификаторы могут быть опасными, поскольку появляется возможность изменить скомпилированную сборку так, чтобы ее идентификаторы содержали «странные» симвоПринципы безопасного кодирования для.NET Framework 153 лы, а это, вероятно, нарушит работу сборки (хотя во многих случаях это не создает уязвимости в защите).

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

Продумайте, не может ли злонамеренная программа изменить код при его компиляции. Посмотрите, не возникает ли небольшой промежуток времени, в течение которого злонамеренный код способен изменить исходный код на диске перед чтением компилятором или загрузкой DLL вашим кодом? Если да, защищайте каталог с этими файлами, используя в зависимости от ситуации защиту по правам доступа кода или список управления доступом (Access Control List, ACL) файловой системы.

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

Выполняйте сгенерированный код с наименьшими возможными разрешениями (используя PermitOnly или Deny).

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

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

Шифрование и подписи

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

154 Защита кода и данных

Случайные числа

Если для системы защиты нужно генерировать случайные числа и требуется, чтобы они были истинно случайными, используйте System.Security.Cryptography. RandomNumberGenerator Применение генераторов псевдослучайных чисел приводит к их предсказуемости, чем может воспользоваться злоумышленник.

Проблемы установки

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

1. Настройте систему на использование двух разделов жесткого диска.

2. Переформатируйте второй раздел; не изменяйте ACL по умолчанию в корневом каталоге диска.

3. Установите свою программу, сменив каталог установки на каталог, создаваемый во втором разделе.

Проверьте следующее.

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

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

3. Есть ли файлы в системном каталоге или его подкаталогах, доступные для записи пользователям, отличным от администраторов?

Кроме того, если программа взаимодействует с Web, учтите, что при работе с некоторыми Web-серверами пользователям разрешается запускать команды, часто выполняемые в контексте учетной записи IUSR_MACHINE.

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

Кит Браун Безопасный код Обзор расширений S4U Kerberos в Windows Server 2003* В этой рубрике рассматриваются новые расширения Kerberos, которые получили общее название Service-for-User (S4U); они позволяют разработчикам задействовать встроенную модель защиты Windows с хорошо знакомой администраторам схемой авторизации на основе членства в группах.

Нелегко создавать Web-сайты, работающие через корпоративный брандмауэр. Обычно внешним пользователям нежелательно назначать учетные записи корпоративного домена, а с чисто практической точки зрения работа Kerberos через Интернет неприемлема из-за типичной конфигурации клиентских брандмауэров. Следовательно, сайт должен поддерживать какой-то механизм аутентификации и авторизации, отличный от встроенных в Windows.

Для решения этой и других проблем, о которых я расскажу ниже, Microsoft реализовала два расширения Kerberos для применения на серверах. Эти расширения получили общее название Service-for-User (S4U); они позволяют разработчикам задействовать встроенную модель защиты Windows с хорошо знакомой администраторам схемой авторизации на основе членства в группах.

Публиковалось в MSDN Magazine/Русская Редакция. 2003. N° 4 (апрель). — Прим. изд.

Защита кода и данных В этой статье я исхожу из того, что у вас есть базовое представление о КегЬеros. Такое представление можно получить из статьи «Exploring Kerberos, the Protocol for Distributed Security in Windows 2000», опубликованной в номере «Microsoft Systems Journal» за август 1999 г. (http://www.microsoft.com/ msj/0899/Kerberos/Kerberos.htrn). Более детальную информацию см. в книге «Programming Windows Security» (Addison-Wesley, 2000). Спецификацию по Kerberos см. в RFC 1510 на сайте IETF (http://www.ietf.org/rfc/rfcl5iO.txt).

Распознавание информации, необходимой для авторизации Первое расширение, о котором я расскажу, помогает серверу определить группы, к которым относится пользователь в домене. Инфраструктура авторизации Windows так усложнилась, что разработчику серверного ПО стало практически невозможно определять эти группы вручную, Глобальные группы (global groups) задаются в основном домене (home domain) пользователя, универсальные (universal groups) могут определяться в любом домене из основного леса (home forest) пользователя и хранятся в глобальном каталоге, а локальные группы домена хранятся в домене сервера.

И все эти группы могут быть вложенными. Поскольку локальные группы хранятся на сервере, с ними работать проще всего. Функция SIDHistory в Windows 2000 приводит к тому, что для некоторых пользователей приходится неоднократно выполнять операцию раскрытия групп (group expansion). А из-за другой функции, называемой карантином в домене (domain quarantine), некоторые группы могут быть удалены. Короче, самостоятельное определение членства доменного пользователя в группах — просто кошмар для разработчика, и этого следует избегать.

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

При аутентификации через Kerberos основную работу, выполняют контроллеры домена. Единственная проблема в том, что для аутентификации через Kerberos в интересах клиента серверу нужны основные удостоверения защиты (primary credentials) клиента, т. е. его пароль или TGT (ticketgranting ticket) и соответствующий сеансовый ключ (session key).

Если бы сервер знал пароль пользователя, то вот как просто было бы получить маркер для клиента под именем Alice в домене sales:

HANDLE hToken;

tf (LogonUserfalice", "sales", alicesPassword, LOGON32_LOGON_NETWORK, 0, ihToken)) { // hToken содержит маркер со всеми группами для Alice I Обзор расширений S4U Kerberos в Windows Server 2003 157 Очевидный недостаток — на сервере должен храниться пароль пользователя, что резко снижает уровень безопасности.

S4U2Self Решение, предлагаемое S4U, заключается в том, что сервер проходит через процедуру аутентификации Kerberos и регистрирует клиент, не предоставляя его удостоверений. То есть на самом деле аутентификация клиента не производится — сервер лишь получает идентификаторы защиты (SID) для групп, в которых состоит клиент. Чтобы это было возможным, контроллеры домена под управлением Windows Server 2003 теперь принимают новый тип запросов Kerberos, в которых сервис запрашивает себе билет (ticket) клиента, применяя для этого собственные удостоверения вместо удостоверений клиента. Это расширение называется Service-for-Userto-Self(S4U2Self).

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

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

LsaLogonUser. По своему духу это похоже на показанный мною вызов LogonUser, однако указывать пароль клиента здесь не требуется. В результате возвращается маркер, который сервис может использовать с такими функциями, как AccessCheck и CheckTokenMembership, а также с новым семейством функций авторизации AuthZ. Это позволяет сервису проверять права доступа по дескрипторам защиты (security descriptors) управляемых им объектов.

Для защиты клиента LsaLogonUser обычно возвращает маркер с особым ограничением. Маркер будет соответствовать уровню олицетворения (impersonation level) Identify, который означает, что сервису не разрешается открывать объекты ядра, подменяя клиент по этому маркеру. Однако сервисам из состава доверяемой вычислительной базы (trusted computing base, TCB), например сервисам SYSTEM, LsaLogonUser вернет маркер с уровнем олицетворения Impersonate, разрешающим доступ к локальным объектам ядра по идентификации клиента. Это не дает недоверяемым сервисам поднимать уровень своих локальных привилегий по билету S4U2Self.

Чтобы задействовать этот механизм, достаточно вызвать LsaLogonUser. Но ее вызов непрост, так как она принимает 14 аргументов, в том числе указатели на структуры переменной длины и описатели (handles) тех или иных сущностей, которые должны быть предварительно открыты.

В Microsoft ±58 Защита кода и данных.NET Framework 1.1 (на момент написания статьи была в бета-версии) включен новый конструктор класса Windows Identity, радикально упрощающий всю процедуру:

public Windowsldentity(string userPrincipalName);

На рис. 1 показан пример С++-кода, напрямую вызывающего LsaLogonUser для запроса регистрации S4U2Self.

Рис. 1. Вызов LsaLogonUser «define UNICODE «define.UNICODE «include windows.h «include ntsecapi.h Ktnclude stdio.h

–  –  –

HANDLE _s4uLogon{eonst wchar_t* pszUserPrincipalNaiee) { // Подключаемся к Local Security Authority, // Это пеовойит получить маркер через S4U2Self // (заметьте, у нас нет привилегий ТСВ, чтобы использовать // этот маркер для доступа к объектам ядра), HANDLE hlsa;

_qheeknte r r( L" LsaConoectUnt rusted ", tsaConnectynt rusted (Shlsa) ) ;

// проверяем индекс провайдера аутентификации Kerberos LSA_ST8ING pkgHame;

ULONG authnPkg;

_cnecknterr(L"LsaLookupAuthenticatlonfackage", LsaLookupAuthenticatioriPackageCnlsa, &pkgName, &authnPkg));

const DWORD cchUPN = lstrlenpszUserPrlncipalNMe);

WiORO cbUPN = cefcUPN * sizeof(wcnar_t);

// Для правильной работе LsaLogonUser // KERB_S4U_L№UK надо передавать как один // непрерывный буфер, содержащий все строки const DWORD Cblogon = sizeof{KER8_S4U_LOGON) + cbUPN;

КЕРВ_84и_1»Ш1* s4uLogon = ( KERB_S4U_LOGON* )calloc GbLogon, 1 ) ;

s4uLogon-«essageType * KerbS4ULogon;

s4uLogon-ClientUpn. Buffer « wchar_t*)((cNir*)s4uLogon + sizeof *s4ulogon);

^3pyHeBiory(34uLogon»ClientUpn.fiuffer, psziiserPrinGipalNeHie, cbUPN);

84uLogon-CliestUpn, Length = (U^ORT)ebUPN;

s4uLoflon-ClientUpn,KaxiEiiueiLength Эта информация копируется в возвращаемый маркер.

// SoyreeName - ASCII-буфер длиной В символов.

TGKEH_SOUJ!CE tokenSource;

AllQcateLoeally4JniqueId(&tokenSource.SourceIdentifier);

strcpyttokenSource.SojrceNarae, "test");

tSA_S"raiMG origirWame;

_8iftoriginNaBe, "ШМ S4U Logon Sanple1');

–  –  –

void mairtO i HANDLE htok s _84uLogon(L"aliceeesec,com");

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

В Windows 2000 введен механизм неограниченного делегирования (unconstrained delegation), позволяющий клиентам делегировать удостоверения защиты определенным сервисам, помеченным как «доверяемые для делегирования» («trusted for delegation»). Под словом «неограниченное» в данном случае подразумевается, что сервис имеет право применять эти удостоверения в Обзор расширений S4U Kerberos в Windows Server 2003 161 любой точке сети сутки напролет. Однако такой механизм используют очень немногие. Тому две причины: во-первых, компрометация сервиса, доверяемого для делегирования, влечет за собой компрометацию всех делегированных удостоверений, превращая этот сервис в приманку для хакеров. А во-вторых, вы должны полностью доверять локальному администратору этого сервиса, поскольку он может повысить уровень собственных привилегий, неправильно используя в сети удостоверения, делегированные клиентом. Очевидно, что этот механизм применим лишь в очень редких случаях.

Ограниченное делегирование или S4U2Proxy Реализация Active Directory в Windows Server 2003 значительно превосходит версию из Windows 2000 и поддерживает более практичную модель ограниченного делегирования (constrained delegation). Идея в том, что сервису по-прежнему можно делегировать удостоверения клиента, но контроллеры домена гораздо избирательнее выдают такие удостоверения. Например, если сервис А запрашивает билеты Kerberos для сервиса В, используя делегированные удостоверения клиента, контроллер домена сверяется со специальным списком, чтобы узнать, имеет ли сервис А право делегировать удостоверения сервису В. Иначе говоря, администратор сети может контролировать область действия делегирования.

AppServer Properties

–  –  –

Пример — СОМ+-сервис, в котором размещена бизнес-логика. Ему может потребоваться доступ к удаленной базе данных по удостоверениям клиента. Администратор вправе выдать данному СОМ+-сервису привилегии ограниченного делегирования, разрешив ему делегировать удостоверения только сервису базы данных. На рис. 2 показано, как настроить такую схему, используя оснастку Active Directory Users and Computers. Здесь СОМ+сервис выполняется под встроенной учетной записью Network Service на компьютере AppServer, а удаленная база данных расположена на компьютере DataServer. Сравните это с реализацией в Windows 2000, где единственный выбор заключался в установке или сбросе флажка, разрешающего неограниченное делегирование (рис. 3).

LA-KEITH Properties Вепиа! Operating System j MembetQf ] Lacatioi'j Managed By!

–  –  –

Tsust спщрйе Idf delegation \ This seeuiitji-sehsitive option means thai services Рис. З. Неограниченное делегирование Согласно RFC 1510, Kerberos поддерживает механизм ограниченного делегирования, известный как билет прокси (proxy ticket), но клиент должен запрашивать эти билеты в интересах сервиса. Microsoft-расширение для Kerberos — S4U2Proxy (Service-for-User-to-Proxy) — позволяет сервису получать билеты от имени клиента, исходя из конфигурационных параметров Active Directory. Благодаря S4U2Proxy сервис может получать билеты для другого сервиса (прокси) в интересах пользователя. Это значит, что клиент должен доверять каталогу (и его администраторам), поскольку он больше не контролирует то, как делегируются его удостоверения.

С технической точки зрения, S4U2Proxy сильно отличается от обычного нрокси-делегирования Kerberos тем, что в стандартном Kerberos для полуОбзор расширений S4U Kerberos в Windows Server 2003 165 Билеты S4U2Proxy недействительны, если путь от клиентского домена к домену целевого ресурса проходит более чем через два леса. Причина этого в том, как работает механизм межлесовой фильтрации идентификаторов защиты (cross-forest security identifier filtering).

Как я уже говорил, LsaLogonUser функционирует по-разному в зависимости от наличия у вызывающего привилегии ТСВ. Если до вызова LsaLogonUser сервису выдана привилегия ТСВ, функция вернет маркер, по которому можно получать доступ к локальным ресурсам компьютера, иначе это будет запрещено в маркере на уровне олицетворения. Здесь безразлично, установлен ли флаг forwardable, так что технически вы можете получить маркер, который можно олицетворять и применять для делегирования удаленным сервисам, но при олицетворении вам будут недоступны все локальные объекты ядра. Пример — сервис, выполняемый как NETWORK SERVICE (в противоположность SYSTEM), которому выдано право на ограниченное делегирование.

Обращаю ваше внимание: для краткости я говорил, что сервису должны быть выданы те или иные привилегии. Под этим я подразумевал, что привилегии должны быть присвоены учетной записи, под которой выполняется этот сервис. Так, если сервис работает под учетной записью Bob, привилегии следует выдать именно Бобу. Если сервис выполняется как NETWORK SERVICE или SYSTEM, он выступает от имени самого компьютера, и тогда соответствующие привилегии должны быть назначены учетной записи этого компьютера.

Заключение Тесная связь авторизации и аутентификации — и благо, и проклятье. Преимущества очевидны. Когда клиент получает билет Kerberos, контроллеры домена записывают в них SID-идентификаторы групп, что исключает лишние сетевые запросы при авторизации. Упрощается и администрирование. Недостаток в том, что получить данные авторизации можно только через аутентификацию Kerberos, и расширения вроде только что рассмотренных ничуть не облегчают взаимодействие с другими реализациями Kerberos. Еще один ограничивающий фактор — двусторонние доверительные отношения между лесами, необходимые для того, чтобы эти механизмы могли действовать через границы леса.

Кит Браун (Keith Brown) работает в DevelopMentor как исследователь, технический писатель и преподаватель. Разъясняет программистам концепции безопасного кода. Автор книги «Programming Windows Security» (Addison-Wesley, 2000). С ним можно связаться через http://www.develop.com/kbrown.

Уэйн Берри

Новые средства 115 надежно защищают информацию и серверные процессы*

В процессе развития MS основное внимание уделялось совершенствованию его защиты. IIS 6.0 — часть Windows Server 2003 — обладает улучшенной защитой, и, кроме того, изменен подход к его настройке. Новые средства MS, в том числе MS LockDown, как никогда раньше упрощают защиту вашего сервера от атак. В статье объясняется, как и зачем завершать работу служб с помощью MS LockDown. Автор также рассматривает TCP/IP-фильтрацию, с помощью которой можно ограничивать доступ к портам, управление обслуживанием файлов по их расширениям, новую функциональность для SSL, применение URLScan и многое другое.

Вы наверняка заметили, что Microsoft прилагает очень много усилий в области безопасности. На это указывают недавно выпущенные инструментальные средства для IIS 5.0 и переработанная архитектура защиты в IIS 6.0, поставляемом с Windows Server 2003. Безопасность — широкое понятие, включающее аутентификанию, авторизацию, шифрование и защиту от попыток проникновений. Хотя предыдущие версии IIS поддерживали шифрование и аутентификацию, защита в других сферах, например от проникновений злоумышленников, атак типа «отказ в обслуживании»

(denial of service) и Web-вирусов, возлагалась на брандмауэры (firewalls).

Публиковалось в MSDN Magazine/Русгкая Редакция. 2002. № 3 (сентябрь). — Прим. изд.

Новые средства IIS надежно защищают информацию и серверные процессы 167 В IIS 6.0 и новых средствах для IIS 5.0 особое внимание уделяется защите Web-сервера от атак. Об аутентификации рассказывал Джеф Просиз (Jeff Precise) в своей статье «ASP.NET: An Introductory Guide to Building and Deploying More Secure Sites with ASP.NET and IIS», состоявшей из двух частей (см. номера «MSDN Magazine» за апрель и май 2002 г.). В этой статье рассматриваются предотвращение проникновений, URLScan, IIS LockDown для IIS 5.0, новые средства IIS 6.0, связанные с защитой, а также функциональность Web-сервера, запланированного к выпуску вместе с Windows Server 2003.

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

Первый шаг в пресечении попыток проникновения — ограничение круга лиц, имеющих права на размещение файлов в корневом каталоге Web-сервера; для запуска помещенной туда ASP-страницы не требуются никакие дополнительные разрешения. С той же целью следует запретить посторонним лицам загрузку файлов через HTTP, WebDAV или расширения FrontPage. Кроме того, надо блокировать злоумышленникам доступ к специальным файлам, в том числе к системным файлам Windows, и запретить их изменение.

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

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

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

Вот что однажды произошло со мной. Один мой приятель должен был передать мне файл по FTP. Я запустил FTP-сервер, установленный вместе с IIS 5.0, и разрешил привилегии записи для анонимного пользователя. Вообще-то я знал, что тем самым я прямо-таки напрашиваюсь на неприятности, но приятель сказал, что он немедленно закачает файл. И сделал это — только через три дня, а за это время два типа закачали на мой сервер полнометражные фильмы и бесплатно использовали мой канал связи и место на сервере. Хотя на моем жестком диске достаточно места для хранения этих фильмов, хакер вполне мог бы чем-нибудь заполнить весь диск и поставить сервер на колени. (Не говоря уже о том, что я стал распространителем незаконной продукции.) Для атак такого рода применяются сканеры портов и другие хакерские инструменты, обнаруживающие уязвимые машины из случайного диапазона IP-адресов. Некоторые машины в моей сети сканировались каждые 20 минут.

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

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

Защита IIS 5.0 Недавно Microsoft выпустила два новых инструмента, которые упрощают администраторам IIS 4.0, 5.0 и 5.1 защиту серверов от проникновения: IIS LockDown и URLScan. В мастер IIS LockDown Wizard встроен интерфейс, позволяющий защищать сервер за счет установки URLScan, изменения параметров метабазы и отключения неиспользуемых служб. URLScan отслеживает входящие запросы URL и отсекает те из них, которые адресованы файлам вне области Web-сайта.

Мастер IIS LockDown в интерактивном режиме определяет, какие именно функции должны работать (рис. 1).

Новые средства MS надежно защищают информацию и серверные процессы 169 *Ч Internet Inforni.ilion Servites Lui.kijuwii Wt?artl Select Seivei template You can easily configiHe Ihis server by selecting Ihe template thai most closely matches its rote.

SmalBusiness Server 2000 Exchange Server 5.5 (0 Ли*. Web Access] Exchange Server 2000 (OWA,PF Management, IM, SMTP, NNTP] SharePoint Portal Server Commeice Seiver 20CD Static Web server Dynamic Web server [ASP enabledj Other [Server that does not match any of the listed role Iha* rliw: nn) im-itr» \K

–  –  –

Рис. 1. Серверные шаблоны в LockDown Wizard Если вас беспокоит уязвимость расширений FrontPage, WebDAV или возможность несанкционированного запуска опасного сценария, изменяющего содержимое вашего Web-сервера, IIS LockDown запретит запись в Web-каталоги по анонимной учетной записи и отключит WebDAV (рис. 2). Администраторы, использующие фиксированный список динамических расширений (скажем, только ASP-файлы), обнаружат, что IIS LockDown удаляет все IDC-, STM- и PRINTER-файлы, а также другие типы динамических сценариев. Кроме того, IIS LockDown может восстановить исходные параметры защиты метабазы IIS и ACL (Access Control List) файловой системы, настраиваемые при установке по умолчанию, и создать резервную копию метабазы перед установкой на тот случай, если ваш Web-сайт окажется неработоспособным с новыми параметрами защиты.

В IIS 5.0 HTTP- и SMTP-серверы устанавливаются по умолчанию, а установка FTP- и NNTP-серверов предлагается как дополнительный вариант;

с помощью мастера IIS LockDown все эти службы можно настроить на запуск вручную. Так как серверы, где эти службы запущены, но не используются, могут быть атакованы кем угодно — от спамеров, использующих SMTP-сервер как открытый сервер ретрансляции, до хакеров, ищущих свободное дисковое пространство на вашем FTP-сервере, — то незадействованные службы полезно отключать.

URLScan — это ISAPI-фильтр, который отслеживает все входящие запросы и проверяет, не являются ли они попыткой атаки на систему (например, вируса Code Red или Nimda). Обычно хакеры пытаются переполнить Защита кода и данных буфер Web-сервера, чтобы получить доступ к операционной системе, или заставить этот сервер запустить либо как-то иначе манипулировать файлами, доступ к которым запрещен.

4f internet Information Services Lorkdowri Wiza Applying Security Setting* Please wait while the n«ad apple; the security settings you selected..:

Dergiing exfetute permission tot system «liitajs toanarjienoususa'accewk.

–  –  –

Рис. 2. Отключение WebDAV Переполнение буфера возникает, когда происходит обращение к памяти за пределами выделенного для задачи диапазона. Это может случиться, если программист не проверяет, помещаются ли переданные программе данные в отведенный им объем памяти. Так как многие приложения выделяют память под URL, для переполнения буфера обычно посылаются длинные URL. Чтобы защитить приложения, которые могут получать такие данные (IIS, ASP, SSL, пользовательские ISAPI-фильтры и т.д.), URLScan отбрасывает URL, длина которых превышает некую заданную величину. Как и остальные параметры URLScan, максимальная длина URL задается администратором.

URLScan также блокирует применение в запросах символов, отличных от ASCII. Обычно такие символы посылаются на сервер сразу после переполнения буфера и представляют собой машинный код, который по замыслу хакера должен выполнить Web-сервер. Запретив прием таких символов, вы оградите свой сервер от атак этого типа.

URLScan позволяет администратору Web-сервера ограничивать размер запросов, обрабатываемых сервером, и размер ответов. Первое дает возможность предотвратить переполнение буфера, а второе — защититься от перегрузки системы (еще один тип атак).

Новые средства IIS надежно защищают информацию и серверные процессы 171 URLScan можно настроить на запись в журнал всех запросов, нарушающих установленные правила. Это особенно полезно, когда URLScan настроен на жесткие ограничения: по журналу легко определить, какие из легальных запросов отклоняются вашим сервером.

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

Кстати, один из самых простых способов для внутренних злоумышленников проникнуть в вашу систему — совместное использование общих ресурсов на уровне дисков, настраиваемое по умолчанию. Например, с$ — скрытый общий ресурс на каждом компьютере под управлением Windows NT и Windows 2000. Обратиться к такому ресурсу можно по UNC-пути: \\имя_машины\с$. Поэтому после установки операционной системы настоятельно рекомендуется отключать подобные общие ресурсы.

Что нового в IIS 6.0 В защиту ITS 6.0 внесено три основных изменения, которые уменьшают риск проникновения. При установке Windows Server 2003 IIS устанавливается, только если вы этого требуете. По умолчанию IIS обслуживает лишь статические файлы. Для обслуживания динамических файлов нужна специальная настройка. Кроме того, по умолчанию IIS 6.0 полностью закрыт (locked down), но для разрешения работы приложений предоставляется простой в применении интерфейс. Другое усовершенствование в защите связано с новой архитектурой обработки запросов в IIS 6.0, включающей многократное использование процессов (process recycling). Администратор может легко устанавливать большинство обновлений защиты IIS и новые DLL рабочего процесса, не прерывая работу сервера. К дополнительным средствам изоляции относятся управление полосой пропускания и распределением процессорного времени, а также рециклинг на уровне памяти (memory-based recycling). Эта функциональность создает среду для независимой защиты нескольких сайтов на одном Web-сервере.

В IIS 6.0 способ регистрации по умолчанию при базовой и анонимной аутентификации изменен HaNETWORK_CLEARTEXT.

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

Защита кода и данных При атаках на Web-сервер хакеры часто пользуются доступными через него утилитами командной строки. IIS 6.0 блокирует запуск таких программ.

Получив доступ к Web-сайту, хакеры часто удаляют его контент. Б US 6.0 предусмотрена защита контента от записи, и анонимные Web-пользователи не смогут перезаписывать информационное наполнение сайта. Ограничения на закачивание данных позволяют администраторам лимитировать данные, которые злоумышленник может загрузить на сервер. Таймауты, ранее слишком длительные, в IIS 6.0 более «агрессивны», а рабочий процесс теперь распознает переполнение буфера и завершает соответствующую программу. Более того, ядро сервера, прежде чем передавать запрос обработчику расширения ISAPI, проверяет имеется ли нужный контент.

На одном Web-сервере все чаще запускается множество приложений или сайтов. Это налагает на Web-сервер определенные ограничения. Например, если провайдер размещает на одном Web-сервере сайты двух компаний (возможно, конкурирующих), эти сайты должны быть полностью изолированы друг от друга. Такой уровень изоляции в IIS 6.0 предоставляется через конфигурируемую идентификацию (configurable identity) рабочего процесса, управление полосой пропускания и распределением процессорного времени, а также рециклингом на уровне памяти.

Рабочий процесс запускается под новой учетной записью с ограниченными привилегиями — NetworkService. Один из важнейших принципов безопасности — выдавать учетным записям лишь необходимый для работы по ним минимум привилегий. Так как у NetworkService очень низкий уровень прав в операционной системе, у несанкционированно запущенных приложений меньше шансов воспользоваться прорехами в защите. Кроме того, в Windows Server 2003 введена фильтрация портов на уровне TCP/IP.

Windows Server 2003 Продукты из семейства Windows NT Server уже давно используются в качестве файл-серверов, и лишь с недавних пор они стали и надежными Web-серверами. IIS в Windows 2000 выпусков Server и Enterprise устанавливается автоматически. В зависимости от лицензии IIS при установке Windows Server 2003 по умолчанию либо полностью блокируется (подробнее об этом режиме — чуть позже), либо вообще не устанавливается.

То есть, если вам*нужен почтовый сервер, SQL сервер или просто операционная система, самостоятельно удалять US для большей безопасности не требуется. IIS поставляется со всеми версиями Windows Server 2003 и устанавливается отдельно.

Новые средства IIS надежно защищают информацию и серверные процессы 173 Кроме того, IIS отключается при обновлении сервера до Windows Server 2003, и при необходимости его нужно включать вручную. Это сделано специально, чтобы не допустить случайного переноса сомнительных настроек из предыдущих версий в новую. Администраторы доменов могут запрещать пользователям установку IIS на компьютерах с Windows Server 2003.

Усовершенствования в SSL IIS 6.0 предоставляет более совершенную реализацию SSL. Помимо расширенной настройки производительности, IIS 6.0 предлагает администраторам удаленно управляемый сертификационный объект и выбор провайдера криптографического сервиса.

В IIS 5.0 удаленно управлять SSL-сертификатами нельзя, так как хранилище сертификатов провайдеров криптографических сервисов (CSP) не предусматривает удаленного доступа.

CertObject (новшество IIS 6.0) позволяет администраторам управлять сотнями или даже тысячами серверов IIS с помощью SSL-сертификатов.

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

ТСР/1Р-фильтрация Другое средство защиты — TCP/IP-фильтрация портов в рамках сетевой конфигурации операционной системы. Данный термин в определенной мере неправилен, так как это средство фильтрует TCP, IP и UDP. Однако TCP/IP-фильтрация действительно повышает безопасность Web-сервера.

В Windows 2000 при назначении IP-адреса любое приложение, запущенное в ящике IIS (IIS box), способно отслеживать любой порт на этом IPадресе, т. е. некое приложение или служба может использовать порты без вашего ведома. Пример такого приложения — интерфейс Web-администратора, доступ к которому осуществляется через порт 8080. Иначе говоря, какое-либо лицо с внутренней стороны брандмауэра или даже приложение в самом ящике IIS могло бы через порты открыть этот ящик для атак.

–  –  –

Area Network Settings. Щелкните кнопку Advanced и перейдите на вкладку Options. Выберите TCP/IP Filtering, затем щелкните кнопку Properties.

Появится диалоговое окно TCP/IP-фильтрации, где вы указываете фильтруемые порты (рис. 3).

Рис. 3. ТСР/1Р-фильтрация Здесь вы можете соблазниться выбрать Permit Only и задать порт 80, ограничив трафик исключительно Web-запросами. Но тогда вы не сможете пересылать файлы на этот компьютер, отправлять и принимать электронную почту, запускать FTP-сервер и т. д. Прежде чем закрывать все порты, стоит провести небольшое исследование. К призеру, если вы используете SSL и FTP-сервер, вы должны открыть порты 443 и 20*. Так как вам нужен доступ к данному компьютеру по TCP/IP, эти порты следует добавить не только в столбец TCP, но и в столбец UDP Если вы хотите получать с

ASP-страницы имя базы данных SQL Server по имени компьютера, на котором она находится, например:

Х Set оСопп = Server. CreateObject("AOODB. Connection") oConn.Open "Trusted_Connect ion-yes; drive r=SQL Server; serve r=SQLMACHINE001;database=NyData; " то откройте порты WINS: 137, 138, 139 (UDP). А чтобы WebTrends могла выполнять обратную DNS-трансляцию применительно к файлам журнала, откройте стандартные порты DNS: 42 (UDP) я 53 (TCP/UDP). Независимо от того, сколько времени займет определение нуждающихся в защите портов, лучше всего выбрать Permit Only и найти эти порты автоматически. Список стандартных портов приведен в табл. 1.

Вам также понадобится порт 21. — Прим. перев.

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

При TCP/IP-фильтрации ограничения на порты можно применять к каждому сетевому адаптеру по отдельности. Это удобно, если у вас, например, два сетевых адаптера, один из которых подключен к внутренней сети и используется для доступа к внутренним ресурсам вроде SQL Server, DNS, WINS и Domain Authentication, а второй — соединен с брандмауэром и применяется для Web-запросов.

Табл. 1. Некоторые стандартные ТСР/1Р-порты

–  –  –

Другие усовершенствования в защите В Windows Server 2003 в качестве механизма аутентификации для IIS 6.0 встроена поддержка Passport. Как только пользователь прошел аутентификацию по Passport, его удостоверения (учетные данные) могут быть отображены на Active Directory локального домена. Local Security Authority (LSA) создает для пользователя маркер (token), применяемый IIS для 176 Защита кода и данных НТТР-залроса. Приложения и Web-сайты могут задействовать эту модель защиты для локальной авторизации пользователей. Новая функциональность Windows Server 2003 — Constrained Delegation (я расскажу о ней чуть позже) — позволяет приложениям делегировать соответствующие удостоверения.

Благодаря URL-авторизации IIS 6.0 можег выполнять авторизацию по конкретному URL. Чем важна эта новая функция? В IIS 5.0 для принятия решения об авторизации применяются ACL. Проблема с этим механизмом в том, что он привязан к объектам, блокируя доступ к отдельным файлам и каталогам, и подогнан под требования файловой системы NTFS. А большинство корпоративных Web-приложений решает бизнес-задачи и привязано к конкретным задачам или операциям. Новая модель авторизации в Windows Server 2003 как раз и отвечает этим требованиям. URL-авторизация IIS 6.0 в сочетании с диспетчером авторизации в Windows Server 2003 позволяет Web-приложению управлять, из единого хранилища политик доступом к URL, которые используются этим приложением и соответствуют специфике его задач и операций.

При авторизации по URL, а не ACL вы должны убедиться, что у процесса есть нужные права. Они выдаются через механизм, называемый делегированием (delegation). Делегирование заключа ется. в разрешении приложениям действовать в сети от лица пользователя. Например, Web-служба в интрасети собирает информацию от нескольких серверов предприятия и через HTTP предоставляет пользователю консолидированный отчет в виде Web-страницы. Этот подход особенно удобен при разработке пакета прикладных программ для развертывания в Windows.

В то же время делегирование сопряжено с рядом потенциальных проблем.

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

Эти проблемы решает такая функциональность Windows Server 2003, как ограниченное делегирование (constrained delegation). Администраторы домена могут разрешить делегирование только компьютерам и службам из ограниченного списка. Делегирование этого вида работает независимо от протокола аутентификации пользователей на сайте.

Новые средства HS надежно защищают информацию и серверные процессы 177 Подводя итоги IIS 6.0 устанавливается в режиме полной блокировки (lockdown mode) и не обслуживает никакие страницы за исключением тех, которые вы указываете явно. Для статических файлов и динамических расширений эта функциональность реализуется по-разному. Статическим файлам не нужно выполнять код в ответ на запрос. К ним относятся графические файлы, HTML-страницы и каскадные таблицы стилей. А динамические файлы (страницы ASP и Cold Fusion), напротив, требуют выполнения.

Страницы с расширениями вроде.htm,.html и.gif обслуживаются, только если они перечислены в MIME Map — новом параметре настройки метабазы ITS, не связанном с сопоставлениями MIME-типов и расширений файлов в операционной системе. Расширения добавляются через новую страницу свойств IIS 6.0; часто используемые типы внесены в список по умолчанию.

Параметр, позволяющий выбирать, какие файлы могут посылаться клиенту для просмотра, весьма полезен. Рассмотрим его использование на примере. Допустим, вы не хотите, чтобы клиенты могли просматривать включаемые файлы (include files). Пусть файл default.asp включает файл sql.inc.

Если бы злоумышленник узнал о файле sql.inc, он смог бы напрямую послать Web-серверу запрос на этот файл и получить его текст, И если в нем содержится имя пользователя и пароль для доступа к базе данных SQL Server, пиши пропало. В IIS 6.0 таких проблем нет: если вы явно не укажете, что файлы с расширением.inc надо обслуживать, злоумышленник не сумеет запросить их. Здесь возникает другой интересный момент. Для правильной работы включаемых файлов не требуется добавлять их расширения в MIME Map. Они будут работать и так, но клиент не сможет получать их текст.

После стандартной (по умолчанию) установки US файлы с динамическими расширениями не компилируются, не запускаются и не обслуживаются.

Чтобы такие файлы обслуживались, их расширения надо внести в список Web Service Extensions. Это блокирует запросы к страницам с незащищенными динамическими расширениями. Таким образом, чтобы ASP-страницы работали после обновления до IIS 6.0, вам придется добавить в этот список расширение.asp. Но, прежде чем добавлять это расширение, убедитесь, что запуск страниц на вашем компьютере безопасен. Например, нельзя разрешать кому попало помещать ASP-страницы в корень Web-сайта. Кстати, заметьте, что при использовании IIS LockDown, поставляемого с IIS 5.0, ваши действия прямо противоположны: там вы запрещаете расширения, здесь — включаете (и можете запрещать, когда они больше не нужны).

178 Защита кода и данных Интересно отметить, что при запросе файла с запрещенным расширением IIS 6.0 возвращает браузеру ошибку «404 file not found», а не «403 access denied», даже если такой файл есть. Это ограничивает объем информации, доступной потенциальным злоумышленникам, и держит их в неведении относительно запрещенных расширений.

Заключение В новом IIS 6.0 ответственность за защиту перекладывается с поставщика программного обеспечения на плечи администраторов. Теперь именно они решают, какие службы включать, а какие — отключать. Усилия, приложенные к обеспечению безопасности IIS 6.0, делают его более защищенным, а инструменты вроде IIS LockDown пред ос таил я ют администраторам пока не обновленных Web-серверов некоторые преимущества IIS 6.O.

Уэйн Берри (Wayne Berry) — архитектор таких продуктов компании XCache Technologies, как XCache, XCompress и XTune. Бывший инженер по проектированию (design engineer) в Microsoft, основатель «15 Seconds» и ASP-разработчик. Имеет опыт в проектировании и разработке ПО, онлайновом бизнесе и консалтинге по вопросам производительности.

Кит Браун Авторизация Ролевая защита на основе Authorization Manager в.NET-приложениях на промежуточном уровне* Authorization Manager в Windows Server 2003 существенно улучшает управление защитой на основе ролей, делает ее более масштабируемой, гибкой и простой в реализации. Используя Authorization Manager, вы можете определять роли и задачи, которые можно выполнять по этим ролям.

Вкладывая роли друг в друга, можно обеспечить наследование характеристик;

кроме того, разрешается определять группы приложений. Authorization Manager позволяет применять сценарии (scripts) для динамического изменения полномочий и ^обертывать» логику защиты в политику безопасности, которая хранится в Active Directory. Authorization Manager также предоставляет простой API для проверки прав доступа. Автор рассматривает все эти возможности и демонстрирует их применение на рабочем примере.

Ролевая защита реализована на платформе Windows, начиная с первой версии Windows NT. На основе ролей операционная система может определять привилегированность процесса, проверять контекст защиты для группы BUILTIN\Administrators. Операционная система исходит из этой логической роли, когда принимает решение, можно ли, например, разрешить вам установку служб или драйверов устройств. При установке операционной системы вы должны определить пользователей, которым назначена эта роль, добавив их в группу Administrators.

Публиковалось в MSDN Magazine/Русская Редакция. 2003. № 11 (ноябрь). — Прим. изд.

Защита кода и данных При введении Microsoft Transaction Services (MTS) и СОМ+, в том числе, была предпринята попытка сделать ролевую защиту более привлекательной для прикладных разработчиков, создав простую инфраструктуру ролевой авторизации для СОМ-серверов. Целью было создание модели доверяемых подсистем (trusted subsystem model) для многоуровневых серверных приложений, где серверные ресурсы доверяют серверу приложений авторизацию запросов. Благодаря авторизации на ранних этапах необходимость в делегировании клиентских удостоверений серверам отпадала.

Делегирование связано с массой проблем — от потенциальной уязвимости защиты до плохой масштабируемости.

Если вы искали универсальное решение для авторизации на промежуточном уровне (middle tier), то вполне вероятно, что ваш поиск завершен.

Знакомство с Authorization Manager Authorization Manager (часто называемый AzMan) — новая универсальная, основанная на ролях архитектура защиты в Windows. AzMan не привязан к СОМ+, поэтому его можно использовать в любом приложении, которому требуется ролевая авторизация, в том числе в Web-приложениях ASP.NET или Web-сервисах, клиент-серверных системах на базе.NET Remoting и т. д.

На момент написания этой статьи Authorization Manager доступен только в Windows Server 2003 и Windows 2000 Service Pack 4; в дальнейшем он будет включен в состав очередного пакета обновлений для Windows XP.

AzMan состоит из двух частей: исполняющей среды и административного Ш. Исполняющая среда, файл которой называется AZROLES.DLL, предоставляет набор СОМ-интерфейсов, используемых приложениями, которым нужна ролевая защита. Административный Ш — это ММС-оснастка, для запуска которой запустите файл AZMAN. MSC или добавьте оснастку Authorization Manager к ММС-консоли. (Заметьте, что административный Ш не работает на более ранних платформах, поэтому для управления AzMan вам потребуется компьютер с Windows Server 2003.) Первое, что вы увидите после запуска административной утилиты AzMan (рис. 1), — это то, что она гораздо сложнее СОМ+. Теперь у нас есть не только роли и их назначения; вам также доступны низкоуровневые операции, которые можно назначать задачам, а те в свою очередь — ротям. Задачи могут включать другие задачи, то же самое относится к ролям. Такой иерархический подход позволяет охватить практически безграничный набор ролей, нужных в современных сложных приложениях.

Теперь о создании задач и ролей. Проектировщик приложения определяет набор низкоуровневых операций, требующих защиты. После этого он определяет набор задач, соответствующих этим операциям. Задачи должны быть Ролевая защита на основе Authorization Manager 181 понятны бизнес-аналитикам, поэтому конкретная задача всегда состоит из одной или нескольких низкоуровневых операций. Если пользователю выдается разрешение на выполнение какой-либо задачи, ему разрешается выполнение и всех операций в задаче. Например, задача Submit Purchase Order («отправить заказ на покупку») может состоять из операций: Acquire Next PO Number («получить номер следующего заказа»), Enqueue РО («поставить заказ в очередь») и Send Notification («отправить уведомление»). Конечно, одну задачу можно всегда сопоставлять одной операции и обеспечить максимальную простоту, но при необходимости поддерживается разделение задач и операций.

–  –  –

Рис. 1. Administration Manager Определив задачи и операции, можно приступать к кодированию и добавить вызовы исполняющей среды AzMan при каждом выполнении защищаемых операций. Вызывать следует lAzClientContext.AccessCheck; пример такого вызова я приведу чуть позже.

При развертывании установочная программа приложения настраивает хранилище AzMan как часть Active Directory или просто как XML-файл, а затем устанавливает базовые низкоуровневые операции и задания. Администратор с помощью оснастки AzMan просматривает определения и описания задач приложения. Затем определяет роли, имеющие смысл в его 132 Защита кода и данных организации. Задача состоит го набора низкоуровневых операций, а роль

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

До сих пор я принимал во внимание только разработчика приложения и администратора, но на самом деле может существовать и третий человек, помогающий в развертывании: автор сценариев бизнес-логики. С каждой задачей можно связать сценарий. Его предназначение — принимать динамические решения, обычно реализуемые вызовами IsCallerlnRole. Это позволяет вынести соответствующую логику ш кода приложения в то место, где администратор может вносить изменения в политику безопасности приложения без модификации и перекомпиляции кода.

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

Первым делом необходимо составить список защищаемых операций:

• чтение каталога;

• заказ книги;

• отметка о выдаче книги;

• отметка о возврате книги;

• добавление книги в хранилище;

• удаление книги из хранилища;

• просмотр истории операций («листка учета») читателя.

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

Если вы хотите опробовать описанное далее, запустите AZMAN.MSC и убедитесь, что вы находитесь в режиме разработки, выбрав Action | Options. СозРолевая защита на основе Authorization Manager 183 дайте новое хранилище в XML-файле, а затем создайте в хранилище новое приложение. После этого добавляйте операции по одной, присваивая им имена и уникальные целые числа, соответствующие номеру операции. Этот номер служит идентификатором операции в вызовах AccessCheck. Обратите внимание, что, присваивая операциям имена, я добавляю префикс ор», просто чтобы избежать совпадений этих имен с именами ролей и задач, которые будут созданы позже, — все имена находятся в одном пространстве и должны быть уникальны.

Оснастка AzMan работает в двух режимах: разработки и администрирования. В режиме администрирования создавать хранилища и приложения нельзя; кроме того, запрещается изменять определения низкоуровневых операций, на которых основан код приложения. Честно говоря, ничто не мешает системному администратору войти в режим разработки и сделать все, что захочется, но смысл в том, что в режиме администрирования UI предоставляет меньше возможностей, упрощая работу администратора и помогая ему избежать ошибок.

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

Oead patron diitory Definition Риоре

–  –  –

обратите внимание на изменение UI: теперь редактировать низкоуровневые операции для приложения запрещено. Добавьте роли для приложения, приведенные на рис. 3.

–  –  –

Рис. З. Роли и задачи Один из способов облегчить себе жизнь в нашем случае — воспользоваться вложением ролей. Например, роль Clerk можно определить через роль Patron, добавив задачи «Check out book» («запись о выдаче книги») и «Check in book» («запись о возврате книги»), как показано на рис, 4. Попробуйте-ка сделать это в СОМ+!

–  –  –

Рис. 4. Вложение ролей Последнее, что необходимо сделать администратору, — превратить абстрактные роли в конкретные, назначив их реальным пользователям. Для этого Ролевая защита на основе Authorization Manager 135 выберите папку Role Assignments и действие Assign Roles. Заметьте: роль не становится активной в приложении до тех пор, пока ее не добавят в эту папку. Например, свойство IAzApplication. Roles возвращает только набор ролей, добавленных к этой папке, а не всех уже определенных ролей. После того как роль назначена, щелкните ее правой кнопкой мыши и добавьте к ней либо пользователей и группы Windows, либо группы приложений, ранее определенные в хранилище AzMan. Группы приложений я опишу позже.

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

Если вы задействуете встроенную в Windows инфраструктуру, скажем, поддержки аутентификации Kerberos для Web-сервера, то сможете получать маркер (token) для клиента. Вообще говоря, это самый естественный способ использования AzMan, поскольку маркер содержит все группы, в которые входит пользователь, а это ускоряет сопоставление пользователя с набором ролей AzMan.

С другой стороны, если для аутентификации вы применяете некую разновидность сертификата Х.50Э, то маркер вы не получите — только имя пользователя. Однако это не означает, что вы не сможете использовать AzMan. Вам даже не понадобится писать никакого дополнительного кода.

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

Приложение сначала должно инициализировать исполняющую среду

AzMan, указать выбранное хранилище и местонахождение в нем параметров приложения. Рассмотрим пример с простым XML-хранилищем:

AzAuthorizationStore store = new AzAuthorizationStoreClassO;

store.Initialized, e"msxml://c:\MyStore.xml", null);

lAzApplication app = store.OpenApplication( "Corporate Library Application", null);

Чтобы собрать это приложение, потребуется ссылка на interop-сборку AzMan, находящуюся в каталоге %WINDIR%\Microsoft.NET\Framework\AuthMan.

Теперь, когда исполняющая среда загружена, вы должны после аутентификации нового клиента создать представление его контекста защиты.

Контекст похож на маркер в том смысле, что в нем хранятся сопоставления пользователя ролям:

1S6 Защита кода и данных lAzClientContext ctx = арр.InitializedlentContextFromToken(htoken, null);

Где же взять маркер клиента? Ну, это зависит от типа создаваемого приложения. Вот, например, фрагмент С#-кода из ASP.NET-страницы, получающий маркер клиента.

Б этом примере в файле web.coring указан режим аутентификации «Windows*, a IIS настроен на использование аутентификации средствами Windows:

Windowsldentity id = (WindowsIdentity)User,Identity;IntPtr htoken = id.Token;

Если вам известно только имя клиента и нет доступа к его маркеру, подумайте, нельзя ли все же как-нибудь раздобыть маркер, потому что маркер — самый надежный способ получить группы, в которые входит клиент.

Кроме того, как я уже упоминал, это самый быстрый способ. Если вы уверены, что до маркера вам никак не добраться, используйте альтернативный способ инициализации контекста по имени учетной записи в форме «домен\пользователь».

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

lAzClientContext ctx = арр.InitializeCHentContextFromName(name, null);

Получив контекст клиента, можно запускать проверки прав доступа. Метод принимает несколько аргументов, но я пока продемонстрирую простои вариант. Допустим, вы реализуете функцию, добавляющую книги к хранилищу. Я определил операцию «Add book to inventory» («добавление книги в хранилище») под номером 5. Код приведен на рис. 5.

Первый строковый аргумент nameOfBook используется, если включен аудит исполняющей среды. Он идентифицирует объект, над которым выполняется операция, поэтому вы должны всегда предоставлять в этом аргументе какую-то описательную информацию. Для второго аргумента, scopes, я оставил значение по умолчанию, смысл которого я объясню позже. Третий аргумент содержит список из одной или нескольких проверяемых операций.

Результатом метода является массив, размер которого совпадает с размером массива операций; в каждый элемент массива записывается целочисленный код статуса для каждой операции, указывающий, разрешен доступ или запрещен. Нуль соответствует успешному результату, т. е. клиенту, определенному в данном контексте, разрешено выполнять данную операцию. Любое другое число означает ошибку (обычно возвращается 5, или ERROR_ACCESS_DENIED).

Ролевая защита на основе Authorization Manager 187 Рис. 5. Добавление книги в хранилище // Всегда определяйте для своих операций константы или пвречишчные) coast int opAddBookToInventory * 5;

const int NQJERROfl - 0;

–  –  –

else { * // Доступ заменен, результат содержит код ошибки Интерфейс исполняющей среды AzMan не является строго типизированным. Для большинства аргументов в нем используется тип VARIANT. Благодаря этому разработчики на классическом ASP, использующие сценарные языки, могут обращаться к AzMan, но разработчики на строго типизированных языках вроде С# и Visual Basic.NET могут допускать ошибки при обращении к AccessCheck, которые будут выявлены только в период выполнения. Так, у массива операций должен быть тип object[], а не int[], однако компилятор не выдаст никаких предупреждений, даже если вы передадите int[], поскольку на самом деле тип аргумента — object. Я споткнулся на этом, когда только начал изучать этот API, и мне потребовалось определенное время, чтобы научиться писать код, не приводящий к ошибкам периода выполнения из-за несовпадения типов параметров. Ходят слухи, что будет выпущен управляемый интерфейс к AzMan, но до той поры вам может понадобиться строго типизированная оболочка AccessCheck, позволяющая избежать ошибок.

Вот пример такой оболочки, попутно упрощающей наиболее распространенный способ вызова этой функции:

public class AzManWrapper { public static int AccessCheckC IClientContext ctx, string objectName, int operation) { object[] results = (object[])ctx.AccessCheck( 188 Защита кода и данных objectName, scopes, ops, null, null, null, null, null);

return (int)results[0];

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

Но не переусердствуйте и не создавайте оболочки для всех интерфейсов — на самом деле проблемы связаны только с этой функцией.

Вероятно, сейчас вас заинтересовало, можно ли применять AzMan, не ставя в соответствие пользователям учетные записи Windows. Архитектура исполняющей среды рассчитана на это, хотя тогда вам придется определять свои идентификаторы защиты (SID) для каждого пользователя. Это не так уж трудно, но вам понадобится вызывать другой метод для инициализации контекста защиты клиента — InitializeClientContextFromStrmgSid. Самая серьезная проблема в том, что вы не сможете использовать оснастку AzMan для управления хранилищами, которые тесно увязаны с пользователями л группами Windows. Дополнительную информацию об этом способе см. в пособии, написанном Дэйвом Мак-Ферсоном (Dave McPherson), ссылка на которое дана в начале статьи.

Хранилища, приложения и области Давайте вернемся чуть назад и обсудим структуру хранилища. Во-первых, у вас есть два способа хранения параметров авторизации: поместить все хранилище в XML-файл или разместить его в Active Directory. Для реальных приложений я настоятельно советую задействовать Active Directory, так она обеспечивает гораздо больше возможностей и зачастую работает быстрее, чем простой XML-файл.

Если у вас есть тестовый домен, попробуйте запустить оснастку AzMan и создать новое хранилище в Active Directory с именем типа «CN^MyStore, CN=Program Data, DC^MyDomain, DC=com», заменив MyDomain на имя вашего домена. Чтобы увидеть объекты, созданные AzMan в Active Directory, воспользуйтесь утилитой вроде ADSIEdit, оснасткой ММС, которую можно установить с компакт-диска Windows Server 2003, запустив SUPPORT\TOOLS\SUPTOOLS.MSI. Создайте приложение в хранилище и Ролевая защита на основе Authorization Manager 189 вызовите его страницу свойств. Вы увидите вкладки Security и Auditing, которых нет при использовании простого XML-файла.

В Active Directory вы можете делегировать ответственность за администрирование отдельных приложений в рамках хранилища и вести аудит изменений в хранилище на очень высоком уровне детализации. При использовании XML-файла вы ограничены защитой самого файла через разрешения NTFS и аудит. В настоящее время аудит поддерживается, только если хранилище находится в службе каталогов, а аудит жизненно важен во многих приложениях. Если Active Directory доступна, настоятельно советую разместить хранилища AzMan там, так как это само подходящее место для хранения политик безопасности в Windows.

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

Каждое приложение может определить несколько областей (scopes), но это продвинутая возможность, которую я рекомендую только тем, кто глубоко изучил AzMan, и только в том случае, если она им действительно нужна. Области позволяют задавать разные параметры авторизации для разных частей приложения. Например, в большом Web-приложении можно назначать разные роли или даже определять абсолютно независимый набор ролей.

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

Если атаки такого типа вам не знакомы, прочтите главу о каноническом формате в книге «Writing Secure Code, Second Edition» (Microsoft Press, 2002).

Чтобы подробнее ознакомиться с продвинутыми возможностями вроде поддержки областей, см. пособие Дэйва Мак-Ферсона, о котором я уже говорил.

Группы приложения В AzMan существует замечательная функция — Application Groups.

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

В AzMan предусмотрено два типа групп приложений: базовые и LDAP-запросов (Lightweight Directory Access Protocol). Базовые группы очень похожи на группы в Active Directory, но с небольшим отличием: вы можете определить как включаемых в нее членов, так и исключаемых. Например, можно определить группу EveryoneButBob («все, кроме Боба»), как я сделал на рис. 6.

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

Группы LDAP-запросов — «дорогостоящая», но очень удобная функция

AzMan. Синтаксис LDAP-запросов можно применять для определения группы пользователей, обладающих некими общими характеристиками. Например, вот как определить набор инженеров, возраст которых старше 21 года:

(&(age=21)(memberOf= CN=eng,DC=foo, DC=com)) Независимо от типа группы приложения администратор может использовать их как альтернативный способ назначения ролей пользователям.

Ролевая защита на основе Authorization Manager 191 Authorization Manager

-Д my*cr*.xrrtl p'1 Groups 3 Я corporate Library Application

–  –  –

Рис. 6. Доступ разрешен всем, кроме Боба Сценарии Когда статических полномочий недостаточно, приложение может предоставлять дополнительный контекст в виде переменных и ссылок на объекты, передаваемых AccessCheck. Это позволяет автору сценария добавить бизнес-логику на языках JScript или VBScript без перекомпиляции приложения. Например, ранее определенной задаче «получить историю операций читателя» можно предоставить дополнительный контекст, содержащий, скажем, набор ролей, которые есть у данного пользователя, и булево значение, указывающее, обращается ли клиент к своей истории или к чужой. Это позволит написать сценарий, разрешающий менеджерам просматривать историю операций любого читателя, но запрещающий обычным пользователям читать любую историю, кроме своей. Вариант сценария, решающего это задачу, приведен на рис. 7.

–  –  –

Рис. 7. Просмотр истории операций читателя exit for end if next if isManager then ' Менеджерам разрешено читать любую историю AzBizRuleContext, BusinessRuleEiesult % true else " Остальным разрешается читать только сво» история self = AzSizRuleContext-GetParameterC'self") Az8izRuleCont«xt.BusinessRuleflesult * self and if Чтобы связать сценарий с задачей «Read patron history», откройте страницу определения задачи, выберите файл, содержащий сценарий, укажите язык (VBScript) и нажмите кнопку Reload Rule into Store.

Поддержка сценариев авторизации Чтобы сценарий, приведенный на рис. 7, работал, нужно передавать при каждой проверке прав доступа, связанной с задачей «Read patron history», дополнительные аргументы. Так как в нашем случае все просто и для каждой операции определена одна задача, вы можете передавать этот контекст (в виде дополнительных аргументов) всякий раз, когда запрашивается соответствующая операция.

Вот фрагмент кода, где демонстрируется передача дополнительного контекста сценарию:

bool self = _userIsCheckingOwnHistory();

object[] operations = { opReviewPatronHistory };

object[] scopes ={""};

object[] varNames = { "roles", "self };

object[] varValues = { ctx.GetRoles(""), self ;

object[] results =: (object[]) ctx.AccessCheck(nameOfPatronHistory, scopes, operations, varNames, varValues, null, null, null);

AzMan в некотором роде привередлив относительно порядка элементов в массивах varNames и varValues. Элементы в varNames должны быть в алфавитном порядке, как у меня. А массив varValues должен содержать значения, соответствующие именованным параметрам в varNames, что в общем-то очевидно. Для большего изящества можно передавать в трех последних аргументах AccessCheck ссылки на именованные объекты. Это раскроет видимую из сценария объектную модель далее за объектом по Ролевая защита на основе Authorization Manager 193 умолчанию AzBizRuleContext. Оставляю вам эксперименты с этой возможностью и решение возникающих при ее использовании проблем в качестве домашнего задания.

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

Конечно, это облегчит жизнь автору сценариев. В своем примере я исповедовал принцип «одна задача — одна операция», чтобы можно было настроить контекстные переменные для каждой задачи, но вспомните: администраторы могут определять новые задачи в режиме администрирования.

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

При создании сценариев следует остерегаться еще одной ситуации. Результаты выполнения сценария кэшируются в объекте клиентского контекста для большей эффективности. Удаление клиентского контекста приводит к удалению содержимого кэша. Об этом полезно помнить, так как некоторые сценарии зависят от внешних данных, изменяющихся со временем.

Помните, что сценарии предназначены для выдачи полномочий ролям или задачам, с которыми они связаны. Допустим, Элис — член ролей R1 и R2.

Роли R1 разрешено выполнять операцию X. Роль R2 имеет те же разрешения, но они определяются сценарием. Когда Элис пытается выполнить операцию X, AzMan даже и не подумает запускать сценарий, связанный с ролью R2, потому что операция X уже разрешена в роли R1. Таким образом, сценарии не могут «отбирать» выданные полномочия. Их можно применять только для того, чтобы выяснить, следует ли учитывать при проверке прав доступа конкретную задачу или роль. Если задаче или роли, с которой связан сценарий, отказано в доступе из-за того, что соответствующий сценарий возвратил false, то это не означает, что нет другой задачи или роли, выдающей разрешение на выполнение проверяемой операции.

Дэйв Мак-Ферсон весьма подробно описывает, как в исполняющей среде реализованы проверки прав доступа. Это описание находится в разделе Performance. Я бы посоветовал внимательно изучить этот раздел каждому, кто на деле планирует использовать AzMan.

7-133 Защита кода и данных Аудит Аудит проверок доступа в исполняющей среде — очень важная функция, доступная только при размещении хранилища Authorization Manager в Active Directory. Если вы хотите включить эту функцию, щелкните имя приложения правой кнопкой мыши, выберите Properties и откройте вкладку Auditing. В период выполнения важна учетная запись, под которой работает серверный процесс: ей необходимо выдать привилегию Generate Audits. Встроенные учетные записи Local Service, Network Service и SYSTEM по умолчанию обладают такой привилегией. Наконец, обратите внимание на то, чтобы результаты аудита сохранялись в журнале событий безопасности; для этого на сервере нужно разрешить аудит доступа к объектам.

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

Заключение Authorization Manager — важное средство создания защищенных систем в Windows. Он расширяет концепцию ролевой защиты, появившейся в MTS и СОМ+, но применим в любом серверном приложении, а не только в СОМ-серверах. Authorization Manager помогает централизовать логику защиты в виде четкой политики безопасности, которую можно хранить в Active Director}' и предоставляет простой API для проверки прав доступа.

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

Кит Браун (Keith Brown) — независимый консультант. Специализируется на защите приложений на платформе Windows. Автор книги «Programming Windows Security» (Ad di son-Wesley, 2000). Преподает в DevelopMentor.

Сейчас работает над новой книгой, доступной через Интернет по ссылке http://www.develop.com/kbrown.

Нирадж Сривастава Безопасность Защита SOAP-пакетов на основе WS-Security и приемников каналов Remoting Все больше организаций использует Web-сервисы XML, поэтому стала очевидной необходимость защиты на уровне сообщений (message-level security). Эту проблему решает WS-Security, теперь поддерживаемая Microsoft.NET Framework. С помощью инфраструктуры WS-Security разработчики могут реализовать приемники каналов (channel sinks) для перехвата Remotingсообщений в процессе их передачи через инфраструктуру удаленного взаимодействия (.NET Remoting). Приемник может прочитать сообщение, изменить его и передать дальше. При этом сообщение можно подписать для большей безопасности. В статье рассказывается, как реализовать приемник канала удаленного взаимодействия, который изменяет сообщение, добавляя в заголовок маркер (token) UserNarrm, а затем подписывая этим маркером тело сообщения.

В последние несколько лет в промышленности бурно растет интерес к Webсервисам XML. Но этот интерес отчасти сдерживало отсутствие спецификации протокола, описывающей защиту на уровне сообщений. Недавно опубликованная спецификация WS-Security является попыткой решить эту проблему. Для поддержки WS-Security в Microsoft.NET Framework используются классы Web Services Enhancements (WSE) 1.0 for Microsoft.NET.

Публиковалось в MSDN Magazine/Русская Редакция. 2003. № И (ноябрь). — Прим. изд.

Защита кода и данных WSE предоставляет инфраструктуру защиты SOAP-сообщений и поддерживает спецификации WS-Routing, DIME и WS-Attachments. Мощная модель программирования, предлагаемая WSE, позволяет работать с SOAPсообщениями напрямую и, в частности, изменять их.

Приемники каналов (channel sinks) — мощное средство расширения.NET Remoting, которое дает возможность перехватывать Remoting-сообщения, передаваемые инфраструктурой удаленного взаимодействия. Приемник может прочитать сообщение, изменить его и передать дальше по цепочке.

В статье рассказывается, как реализовать приемник канала удаленного взаимодействия, который изменяет сообщение, помещая в заголовок маркер UserName, а затем подписывая этим маркером тело сообщения. Поскольку используется WSE, генерируется сообщение, соответствующее спецификации WS-Security (рис. 1).

Рис. 1. Генерация сообщения с помощью WSE

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

При конструировании прокси и вызове метода генерируется объект Message, который при обмене данными с сервером передается по цепочке приемников.

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

В инфраструктуре Remoting имеется несколько классов, реализующих интерфейс IMessage, который предназначен для описания различных сообщений, передаваемых при конструировании (ConstmctionCall, ConstructionResponse) или при вызове методов (MethodCall, Method Response).

Есть два важных приемника, через которые проходят сообщения удаленного взаимодействия: FormatterSink и Transport Sink. FormatterSink сериаЗащита SOAP-пакетов на основе WS-Security и приемников каналов Remoting 197 лизует сообщение в поток и создает транспортные заголовки. TransportSink преобразует транспортные заголовки в заголовки, специфичные для протокола, и передает поток по сети по выбранному протоколу. Вы можете размещать собственные приемники до и после Formatter Sink.

Приемники, находящиеся между FormatterSmk и TransportSink, должны реализовать интерфейс ICHentChannelSink (если это клиентский приемник) или IServerChannelSink (если это серверный приемник). На рис. 2 показана архитектура приемников каналов, а на рис. 3 даны определения этих интерфейсов. Позже я поясню, как реализовать эти интерфейсы.

–  –  –

Рис. 2. Архитектура приемников каналов Рис. 3. Определения интерфейсов Public interface ICHentCharnmlSink { iCliervtChannelSinfc NextChannelSink {get;} void AsyflcProcessRequest(ICHentChannelSinkStac& sinkStack, sg, ITransportHeaders headers, Stream strearo);

–  –  –

Рис. 3. Определения интерфейсов void AsyncProcessResponseCIClientResponseGhanRelSiftkStack sinkStack, object state, ITransportHeatiers headers, Stream stream);

Stream SetfiequestStream (message tesg, ITransportWeaders headers);

void ProcesisHessafle(IMessa{ie rasg, ITransportHeaders requestHeaders, Stream requestStream. out ITransjiQTtHeaders responseHeaderSj out Stream responseStream);

Public interface IServerGhannelSink { IServerChannelSink NextGtiannelSink {get;} void AsyncF'rocessResponsedServerResponseChannelSiRkStack sirtkStack, abject state, message iasg, ITransportHeadars headers, Stream stream);

Stream SetflequestStreain (IServerResponseCHannelSinkStack sinkStack, object state, IHessage resg, ITransportHeaders headers);

void ProcessMessagedSeFverResponseChafinelSinkStack IMessage requestMsg, ITransportNeaders requestJ-teaders, Stream requestStreai», out IHessage respofrse^sfl, out ITransportHeaders responseHeacters, out Stream responseStream);

Любой приемник, вставленный перед FormatterSink, может обращаться только к объекту неформатированного сообщения (raw message object). Такие приемники должны реализовать интерфейс IMessageSink.

Определение JMessageSink выглядит так:

Public interface IMessageSink { IMessageSink NextSink {get;} IMessageSink AsyncProcessHessage (Imessage msg, ImessageSink replySink);

IMessageSink SyncProcessHessage (IHessage msg);

Защита SOAP-пакетов на основе WS-Security и приемников каналов Remoting 199 Обычно FormatterSink — первый приемник цепочки на стороне клиента.

FormatterSink реализует IMessageSink, а также IClientChannelSink (на клиентской стороне) или IServerChannelSink (на серверной стороне).

Приемник форматирующего объекта (formatter sink) на клиенте принимает сообщение по интерфейсу IMessageSink, сериализует его и передает дальше по IClientChannelSink. На сервере процесс идет в обратном порядке, и сообщение передается через интерфейс IServerChannelSink.

Каналы удаленного взаимодействия связываются с цепочкой приемников, используемой по умолчанию. Например, HttpChannel по умолчанию связан с SoapFormatterSink, a TcpChannel — с BinaryFormatterSink.

Можно переопределить цепочку приемников, указав в файле конфигура-.

ции ссылку на собственные провайдеры приемников. Провайдер приемника (sink provider) реализует интерфейс IClientChannelSinkProvider для создания клиентских приемников каналов и интерфейс IServerChannelSinkProvider для создания серверных приемников каналов:

public interface IClientChannelSinkProvider I ICHentChannelSinkProvider Next {get; set;} IClientChannelSink CreateSink (IChannelSender channel, string url, object remoteChannelData);

public interface IServerChannelSinkProvider { IServerChannelSinkProvider Next {get; set;} IServerChannelSink CreateSink (IChannelReceiver channel);

void GetChannelData(IChannelDataStore channelData);

I Цепочка провайдеров инициализируется, когда считывается файл конфигурации и инициализируется канал. Порядок, в котором провайдеры располагаются в цепочке, зависит от порядка их размещения в файле конфигурации. Метод CreateSink провайдера вызывается при создании прокси.

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

WSE-классы Теперь рассмотрим WS-Security и использование маркеров имени пользователя для подписи Remoting-сообщений. Начнем со знакомства с WSEклассами. Вот эти классы и их описания.

200 Защита кода и данных Microsoft.Web.Services.SoapWebRequest Наследует от System.Net.WebRequest и передает SOAP-сообщение через последовательность фильтров, выполняющих преобразования. Этот класс относится к инфраструктуре WSE и для преобразования сообщения обращается к информации класса SoapContext.

Microsoft.Web. Services.SoapContext Содержит информацию, применяемую при преобразовании маркеров защиты сообщений, информацию о маршрутизации (referral information) и вложения. Инфраструктура использует эти данные, чтобы выполнять различные преобразования входных и выходных SOAP-сообщений.

Microsoft. Web.Services.SoapEnvelope Инкапсулирует класс SOAP-конверта и упрощает работу с SOAP-сообщениями.

Microsoft.Web.Services.Security.Security Содержит набор маркеров защиты (таких как маркер имени пользователя) и набор элементов защиты (например подпись). У этого класса имеется метод GetXml, который принимает XML-документ на входе и возвращает XML-подпись, соответствующую спецификации WS-Security.

Microsoft.Web.Services.Security.Signature Содержит подпись, соответствующую маркеру защиты. С помощью этого класса можно подписать несколько разных фрагментов сообщения. В этой статье я буду подписывать только тело SOAP-сообщения.

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

Реализация приемника канала Давайте вкратце рассмотрим работу с приемниками Remoting. Для использования приемника надо написать класс, реализующий интерфейс lUserNameTokenHelper, и класс, реализующий интерфейс IPasswordProvider.

HJserNameTokenHelper объявлен в пространстве имен SecuritySink, реализованном в примере кода к этой статье (см. http://msdn.microsoft.com/ msdnmag/code03.aspx в разделе за ноябрь). Клиентский приемник вызывает методы GetUserName и GetPassword этого интерфейса, чтобы получить имя пользователя и пароль для подписи SOAP-сообщения.

Защита SOAP-пакетов на основе WS-Security и приемников каналов Rerouting 201 В данной реализации я создал в провайдере клиентского приемника свойство TokenHelper, который ссылается на объект, реализующий этот интерфейс.

Интерфейс I Pass word Provider объявлен в пространстве имен Microsoft. Web. Services. Security. Инфраструктура WSE вызывает этот интерфейс, чтобы при проверке подписи получить пароль, соответствующий имени пользователя. Этот пароль служит для подписи SOAP-сообщения: значение его подписи сравнивается со значением, получаемым в SOAP-сообщении.

Класс, реализующий этот интерфейс, указывается в разделе WSE файла app.config.

Кроме того, app.config следует настроить так, чтобы приемник оказался в нужном месте цепочки приемников. В клиентском файле app.config приемник должен находиться после Formatter, а в серверном файле app.config — перед Formatter. Это объясняется тем, что нам нужно работать с сообщением после того, как оно сериализовано на клиентской стороне, но до того, как оно будет десериализовано на серверной. На рис. 4 и рис. 5 показаны соответствующие фрагменты каждого файла конфигурации. На рис. 4 приведен клиентский файл конфигурации, содержащий ссылку на провайдер клиентского приемника канала (в разделе Provider). Кроме того, в разделе Provider содержится ссылка на объект TokenHelper как на одно из свойств провайдера.

Рис. 4. Файлы конфигурации Конфигурация клиентского приемника удаленного взаимодействия channels ref=-"http" clientPrQvlders «formatter ref="soap" / provider type="SecuritySink.SecurityChannelSinkProvltier, SeouritySlnk" TokenHeIper="SecyritySink.TokenHelperObJ,SecuritySiRk'"/ /GltentProvitlers Конфигурация серверного приемника удаленного взаимодействуя

–  –  –

Параметры WSE в app.config на серверной стороне version="1.0" efieodlng="ul:f~8" ?

eonfiguration section nanie="microsoft.vffi[(, services" type= "Microsoft. Web. Services.GoRfi gyration.

We bSecvicesConfiguration, Microsoft. Web. Services, Version=1. 0.0,0, Culture^reutral, PublicKeyTokeR-31bf385Sad364e35" / /configSections fflicrosoft.web.aerviGes security password Provider tyies"$ecuritySink. Password? roviderCIass, SecuritySink" / /secyrity /mic rosof t. web - se rvices /coflfiguration • Рис. 5. Конфигурация сервера versloo="1.Q" configuratiort configSections sectl(Hi (iaKe~"iBicrisoft.web.services" type="Microsoft.We6,Services,Gonfigtiration,WebServicesCoflfi6Mratiofl, Microsoft,Web.Services, Version=1.0,0.0, Culture=ne«tral1 PufrlicKeyToken'=31bf3856a(364e36" / /configSectiOFis Biicrosoft.web.services security passwordl:i rovider type="SeCiiritySink.Passwjrd?roviderCla8S, SecuritySink" / /secarity см. след. стр.

Защита SOAP-пакетов на основе WS-Security и приемников каналов Remoting 203 Рис. 5. Конфигурация сервера (окончание) /microsoft.web.sersrices systeiB.Runtime. RefflQting Application пате="АррНаве"

–  –  –

Заметьте: файлы конфигурации на стороне сервера можно объединить в один файл. Для этого нужно перенести раздел Remoting из файла конфигурации приложения в файл конфигурации сервера и загружать этот раздел на сервере при настройке Remoting. На рис. 5 приведен такой файл конфигурации сервера. Как видите, в разделе Provider содержится ссылка на провайдер серверного приемника канала. Приемник форматирующего объекта и приемники, создаваемые провайдерами, будут вызываться в цепочке в порядке следования соответствующих разделов файла конфигурации.

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

Кроме того, у этого провайдера имеется конструктор, принимающий два параметра:

Защита кода и данных объект словаря и набор SinkProviderData. Объект словаря содержит свойства провайдера приемника, заданные в файле конфигурации, а набор — дополнительную информацию о конфигурации, заданную в файле в элементе provider. Строка, соответствующая маркеру имени пользователя, передается в наборе свойств, а провайдер в свою очередь передает это значение приемнику.

Самый интересный метод провайдера приемника называется CreateSink.

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

Вот как выглядит код, реализующий этот метод:

–  –  –

Client Channel Sink, наследующий от BaseChannelSinkWithProperties, является базовым классом для приемников, поддерживающих именованные свойства. (Такой приемник должен реализовать именованные свойства Keys и Indexer.) Кроме того, объект должен реализовать интерфейс IClientChannelSink. Реализация IClientChannelSink означает, что вы должны также реализовать метод Process Message для поддержки синхронной обработки и процедуры AsyncProcess Request и AsyncProcess Response для поддержки асинхронной обработки. Центральное место занимает закрытый метод SignMessage, выполняющий основную работу по подписанию SOAP-сообщения.

Защита SOAP-пакетов на основе WS-Security и приемников каналов Remoting 205 Перед тем как углубиться в реализацию ProcessMessage, рассмотрим реализацию метода GetRequestStream клиентского приемника канала. GetRequestStream возврашает поток, в который может выполнять запись предыдущий приемник в цепочке. Если он возвращает null, предполагается, что предыдущий приемник в цепочке должен создать собственный поток, чтобы начать цепочку, и передать этот поток следующему приемнику. Если вы собираетесь в своей реализации приемника канала тем или иным образом изменять поток или перемещаться по нему, рекомендуется, чтобы ваша реализация GetRequestStream возвращала null.

ProcessMessage и SignMessage Функция ProcessMessage обрабатывает сообщение перед тем, как передать его следующему приемнику. При этом предварительная обработка поручается закрытому методу SignMessage. Последующая обработка ответа не выполняется.

SignMessage создает объект SoapEnvelope для потока, передаваемого в качестве параметра. Кроме того, он создает вспомогательный объект UsernameToken по строке, считываемой из файла конфигурации и передаваемой провайдером приемника.

Метод получает имя и пароль пользователя из этого объекта:

string helperOb] = _tokenHelperStrlng;

stringd strarry = helperObj.Split(new Split(new C h a r t ] { ', ' } ) ;

ObjectHandle ob] = Activator.Createlnstance(strarry[1],strarry[0]);

IllserNameTokenHelper tokHelper = obj.Unwrap() as lUserNameTokenHelper;

string usr = tokHelper.GetUserNameO;

string pass = tokHelper.GetPasswordO;

При создании UserNaineToken указываются эти имя и пароль пользователя. Далее создается объект защиты, и UserNameToken добавляется в его набор маркеров защиты. Затем создается объект подписи, который инициализируется созданным UserNameToken. Этот объект добавляется в набор элементов защиты объекта защиты.

Рис. 6. Обработка сообщения ff Stream returRStreani;

// Загружаем Soaplftvelope req&iv = яви SoapEnvelopeO;

reqEnv.LoadrequestStreaiB);

–  –  –

Рис. 6. Обработка сообщения ] (окончание) // Создаем маркер имени пользователя ysernaseToken tok = new UsernaBeTokenftoktfelper.GetUserNaffleO.tokHelper.QetPasswordO);

tok.PasswordOption - PasswordOption.SendNone;

// Соэдаеи обьект защиты Security sec * new Security(actor);

sec. Tokens. Add (tok);

if (reqEnv. Header =™ null) reqEnv, CreateHeader( );

// Подпись Signature slg = new Sigfmtyre(tnk);

'// Подписываем regEiw. Header. ApperKlChild(see.Gf!tXinl{ reqEn // Сохраняем ifUflStream ==» null) { inStreaBi = new MeaoryStream();

reqEnv. Save(inStreae);

InStream. Positloft=4;

else

–  –  –

Далее SOAP-кониерт подписывается. Для этого он передается методу GetXml объекта защиты. GetXml возвращает элемент WS-Security Header, добавляемый в заголовок SOAP- конверта. Наконец, новое SOAP-сообщение сохраняется в исходящем потоке. Детали см. в исходном коде на рис. 6.

Асинхронная реализация этих операций не так уж сильно отличается от синхронной. В AsyncProcessRequest текущий приемник помещается в стек Защита SOAP-пакетов на основе WS-Security и приемников каналов Remoting 207 приемников, чтобы этот приемник вызывался при асинхронной обработке ответа. Никакой последующей обработки сообщения не требуется; вместо этого вызов просто передается очередному приемнику.

Реализация серверного приемника канала Реализация ServerChannelSinkProvider аналогична реализации клиентского провайдера. Вы передаете ссылку на объект канала, необходимый для реализации приемника. В настоящее время серверные приемники не поддерживают асинхронную обработку запроса. Однако возможна асинхронная обработка ответа. Поэтому достаточно реализовать только методы Process Message и AsyncProcessResponse. В данной реализации приемника канала ответ сервера не обрабатывается, а просто передается дальше по цепочке. Поэтому реализация метода GetResponseStream всего лишь делегирует вызов следующему приемнику в стеке приемников для дальнейшей обработки. Обработка метода AsyncProcessResponse тоже тривиальна — и в этом случае вызов просто делегируется следующему приемнику в стеке.

В методе ProcessMessage вы должны сначала убедиться, что метод еще не десериализован. Затем создать SOAP-конверт для потока, передаваемого в качестве параметра, а из SOAP-сообщен и я извлечь заголовки WS-Security.

Создавая объект защиты из XML-кода каждого из заголовков, вы проверяете подпись.

При WSE-обработке вызывается объект, реализующий интерфейс IPasswordProvider. Этот объект считывает пароль, соответствующий имени пользователя, которое содержится в заголовке. Конкретный объект, реализующий IPasswordProvider, задается в файле конфигурации WSE в разделе microsoft.web.services... passwordProvider. Чтобы получить дополнительную информацию, изучите файлы конфигурации в примере кода к статье. Кроме того, перед дальнейшей передачей сообщения по цепочке приемников следует удалять заголовки Security из SOAP-сообщения (рис. 7).

В приемниках каналов на стороне сервера очень важно обрабатывать исключения; сгенерированное исключение передается обратно до транспортного приемника, который обрабатывает его и завершает соединение. Необходимо обработать исключение и возвратить соответствующее сообщение SOAP Fault с нужными кодами HTTP-ошибки. Для изменения кодов HTTP-ответа используются ключи транспортного заголовка HttpStatusCode и HttpReasonPhrase.

Защита кода и данных Рис. 7, Обработка элементов зйщиты SoapEnvelope reijEnv = new SoapEnvelopeO;

reqEnv, Load(refjuestStreaft);

// Обрабатываем несколько элементов защиты XffllftodeUst nodelist;

IHmiaerator rtodellstSnuis;

nodelist = reqnv.Header.GetHeBtentsByTagNaiBee"Secarity @"http r //sctramas. xslsoao. о rg/ws/29S2/Q7/saeext " ) ;

nodelistEfluB = nodellst.EetEnunnsratorO;

ArrayList nodestodelete = new ArrayListO;

try { wMle(nodelistEnuifi.MoveNextO) { XmlElement elea = nodelistEnum.Currertt as // СОЗДАЕМ объект защиты Security seeserver * new Security(elee);

// He можем удалить узел, так как список изменится, // поэтому запоминаем узея nocfestodelete.Add(eleit);

–  –  –

XmlElefflent)FiodestodeleteEnum. Current);

} MemoryStreaffl stnr - new KemoryStreanK);

reqnv, SaveCstrfi);

stra. Position^;

processing * „nextSink.ProeesEiMessaflefsinkStack, rtull, cequestHeaders, sitrnt, oot respoflseHsg, out responseHeaders, out responaeStrea»);

В обработчике исключения создается соответствующее исключению сообщение SOAP Fault, которое сериализуется в поток ответа; при этом задаются нужные HTTP-заголовки со сведениями об ошибке на серверной стороне. Если используется TCP-канал, обратно передается лишь сообщение SOAP Fault, а заголовки не устанавливаются.

Защита SOAP-пакетов на основе WS-Security и приемников каналов Remoting 209 Расширение реализации Одно из возможных расширений этого приемника — реализация эквивалента олицетворения (impersonation), или подмены.

Когда подпись проверяется на сервере, на этой стороне имеется допустимый объект защиты, из которого можно получить маркер UserName:

SecurityTokenCollBction col = reqCtx.Security.Tokens;

lEnumerator e = col.GetEnumerator();

e.MoveNextO; // ожидаем только один маркер UsernameToken tokn = (UsernameToken) e.Current;

string username = tokn.Usernane;

Genericldentity idn = new Genericldentity (username);

GenericPrincipal p = new GenericPrincipal (idn, null);

System.Threading.Thread.CurrentPrincipal = p;

Предыдущий фрагмент кода можно расширить, реализовав на сервере ролевую защиту. На клиентской стороне пользователя можно идентифицировать по участнику безопасности потока (thread principal). Еще одна возможная реализация — написать, опять же с помощью WSE, приемник удаленного взаимодействия, шифрующий SOAP-сообщения.

Заключение Благодаря новым WSE-классам, совместимым с.NET Framework, реализовать клиентский и серверный приемники удаленного взаимодействия очень легко. Эти классы упрощают подписание и шифрование SOAP-coобщений, а архитектура цепочки приемников очень удобна для расширения обработки сообщений.

Нирадж Сривастава (Neeraj Srivastava) работает в Microsoft Product Support Services в группе Solutions Integration Engineering. Занимается разработкой около восьми лет, в основном использует технологии Microsoft.

Сейчас специализируется на технологиях разработки ПО промежуточного уровня:

СОМ+, Remoting, Web-сервисы и ASP.NET.

Майкл Говард Оценка уязвимое гей Полезные советы по выявлению уязвимостей в вашем коде Оценка кода на предмет наличия уязвимостей в нем — важнейший этап процесса создания программного обеспечения наравне с планированием, проектированием и тестированием. В статье автор делится своим многолетним опытом оценки защищенности кода и дает ряд советов, которые помогут всем разработчикам выявлять возможные «дыры» в программе. Процесс начинается с изучения среды, в которой выполняется код, определения ролей его пользователей, а также с изучения хронологии присущих данному коду уязвимостей. После того как понимание базовых проблем достигнуто, можно исследовать код на предмет конкретных уязвимостей, в том числе перед атаками с внедрением SQL-кода, с использованием кросс-сайтовых сценариев и переполнения буфера. В дополнение можно проверить код на наличие очевидных, но распространенных «дыр» вроде переменных с именами

-password» или «secret».

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

Надеюсь, вы понимаете: хотя проверка кода, написанного другими, — штука важная, она не является способом создания защищенного ПО. Для создания защищенных программ нужно проектировать, писать, тестировать и Публиковалось в MSDN Magazine/Русская Редакция. 2003. № 11 (ноябрь). — Прим. изд.

Полезные советы по выявлению уязвимостей в вашем коде 211 документировать системы защиты в рамках определенных правил, а также предусматривать оценку безопасности, обучение и использование инструментальных средств. Простым проектированием, написанием, тестированием и документированием, а затем поиском «дыр» защищенную программу не создать. Оценка кода — лишь часть процесса, и сама по себе она не обеспечивает разработку защищенного кода.

В этой статье я не стану обсуждать природу таких уязвимостей, как внедрение SQL-кода (SQL injection) и переполнение буфера. Об этом вы можете узнать из книг, например из моей книги «Writing Secure Code» (Microsoft Press, 2002). Вместо этого я проведу высокоуровневый анализ ошибок, на которые в первую очередь обращаю внимание при оценке кода.

Заметьте:

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

Как мне представляется, есть три способа оценки кода: глубокий анализ, беглый анализ и смешанный подход. Я обычно пользуюсь третьим, так как он позволяет быстро оценивать большие объемы кода. Если мне встречается место, требующее на мой взгляд более глубокого анализа, я помечаю его для более глубокого анализа, возможно, с привлечением других экспертов в данной области. Но сейчас я хотел бы обсудить беглый первоначальный анализ кода — «Огляди и отметь», как я называю этот способ быстрой оценки кода с выделением областей, нуждающихся в более детальном анализе.

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

• Выполняется ли код по умолчанию?

• Выполняется ли код с повышенными привилегиями?

• Принимает ли он данные от сетевого интерфейса?

• Аутентифицируется ли сетевой интерфейс?

• Написан ли код на C/C++?

• Были ли уже связаны с этим кодом проблемы с безопасностью?

Защита кода и данных

• Настороженно ли относятся к этому компоненту специалисты по безопасности?

• Имеет ли дело код с секретными данными?

• Пригоден ли код для повторного использования (например, не является ли он DLL, заголовочным файлом О+-класса, библиотекой или сборкой)?

• Если исходить из модели угроз, то находится компонент в уязвимой среде или подвержен опасным угрозам?

Если я получаю более трех-четырех положительных ответов, то рассматриваю код глубже. Фактически, если код прослушивает сокет TCP (Transmission Control Protocol) или UDP (User Datagram Protocol) и выполняется по умолчанию, готовьтесь потратить на его анализ массу времени.

В поисках уязвимостей я оцениваю три обширные категории кода: код на C/C++, код на Web-сервере (например ASP, ASP.NET, CGI и Perl) и управляемый (в основном на С#, но и на Visual Basic.NET тоже).

В каждом языке есть свои нюансы, о которых следует помнить. Во-первых, основная проблема в С и C++ — переполнения буферов (buffer overruns).

Конечно, есть и другие проблемы, но когда вы слышите о буфере и о переполнении в одной фразе, речь почти наверняка идет о С или C++. Языки более высокого уровня (скажем, С#, Visual Basic.NET и Perl) не подвержены переполнению буфера. А если оно все же возникает, то ошибка скорее всего в исполняющей среде, а не в самом коде. Однако такого рода языки часто применяются для создания приложений на Web-сервере и подвержены другим недостаткам. Переполнения буферов очень опасны, так как злоумышленник может встроить код в выполняемый процесс и скомпрометировать его. Поэтому сначала давайте рассмотрим именно.-ату проблему.

Переполнения буфера в С и C++ Переполнения буферов — проклятие индустрии ПО, поэтому следует приложить все усилия и избавиться от них. А еще лучше, стремитесь к тому, чтобы они вообще не были возможны в вашем коде.

Я оцениваю вероятность переполнений буферов двумя способами. Первый состоит в определении всех входных точек приложения, особенно сетевых, в анализе передачи данных внутри кода и манипулирования ими. Я исхожу из того, что все данные некорректны. Обнаружив код, который обращается к данным (читает или записывает их), я спрашиваю себя: «Какие данПолезные советы по выявлению уязвимостей в вашем коде 213 ные способны вызвать сбой в этом коде?». Это очень тщательный метод, требующий много времени. Другой прием состоит в поиске известных и потенциально опасных конструкций, а затем отслеживания данных обратно до входной точки.

Например, рассмотрим следующий код:

void fuction(char *p) { char buff[163;

strcpy(buff,

Встретив такой код, я отслеживаю переменную р до ее источника, и, если она передается из ненадежного места или не проверяется на корректность рядом с точкой копирования, значит, я нашел «дыру» в защите. Заметьте, что сама по себе strcpy не является опасной или незащищенной. Нет, это данные делают функции типа strcpy опасными. Если вы проверяете данные на корректность, strcpy безопасна. Конечно, если вы где-то ошиблись, то получите «дыру» в защите. Кроме того, я проверяю все «п»-строковые функции типа strncpy, так как необходимо убедиться, что размеры буферов вычисляются правильно.

Я настороженно отношусь к коду, который работает с тэговыми форматами файлов. Под тэговыми я подразумеваю файлы, состоящие из блоков, каждый из которых имеет описывающий его заголовок. Хороший пример — музыкальный формат MIDI. Так, в Windows-компоненте quartz.dll, работающем с MIDI-файлами, была обнаружена и устранена серьезная ошибка защиты. Некорректная MIDI -инструкция вызывала в обрабатывающем коде сбой, а то и что похуже. Подробнее об этой ошибке см. http://www.microsoft.com/technet/ security /bulletin/M S03-030.asp.

Еще один пример конструкций, на которые я обращаю внимание:

–  –  –

Этот цикл ограничен символом в строке -источнике, а не размером строкиприемника.

В основном я ищу конструкции вида *х++ = *у++ с помощью следующего регулярного выражения:

\*\w+\+\+\s?=\s?V\w+\+\+ Конечно, кто-то может пользоваться конструкциями вида *++х = *++у, так что их тоже следует искать. Хочу еще раз подчеркнуть, эта конструкция 214 Защита кода и данных опасна, только если источник ненадежен, поэтому вам нужно определить надежность источника данных.

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

Целочисленное переполнение в С и C++ Если вы не знаете, что такое атаки целочисленного переполнения и как с ними бороться, сначала прочтите мою статью по ссылке http://msdn.microsoft.com/library/en-us/dncode/html/secure06122003.asp. Пробел в защите возникает, когда для вычисления буфера применяются арифметические выражения, вызывающие переполнение или потерю значимости.

Рассмотрим следующий пример:

void func(char *Ы, size_t c1, char *Ь2, size_t c2) { const size_t MAX = 48;

if {c1 + c2 MAX) return;

char «buff = new char[MAX];

memcpy(buff, Ы,с1);

memcpy(buff+c1, Ь2,с2);

Код выглядит нормально, пока вы не осознаете, что если cl + с2 больше 232-1, возникает проблема. Например, в результате сложения OxFFFFFFFQ и 0x40 получается 0x30 (десятичное 48). Если в качестве значений cl и с2 взять эти числа, результат сложения пройдет проверку, и код скопирует примерно 4 Гб в 48-байтовый буфер. Вот вам и переполнение буфера!

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

При анализе кода на С и C++ на целочисленное переполнение, я обращаю внимание на вызовы оператора new и функций динамического выделения памяти (alloca, malloc, calloc, НеарАПос и т. д.), а затем смотрю, как вычисляется размер буфера. После этого я задаю себе такие вопросы.

• Могут ли значения превысить некую максимальную величину?

• Могут ли они оказаться меньше О?

• Обрезаются ли данные (копируется ли 32-битное значение в 16-битное и обратно)?

Полезные советы по выявлению уязвимостей в вашем коде 215 Есть эмпирическое правило, выведенное моим коллегой в Microsoft: если в выражении сравнения выполняется математическая операция, есть вероятность переполнения или потери значимости. Это вдвойне неприятно, если выражение применяется для вычисления размера буфера, особенно если один или несколько элементов выражения испорчены злоумышленником.

Код доступа к базе данных на любом языке Обычно разработчики создают приложения для работы с базами данных на языках более высокого уровня типа С#, языков сценариев и т. д. В общем-то относительно малая часть кода для работы с базами данных написана на С и C++, но некоторые применяют библиотеки классов вроде CDatabase из MFC.

Есть две проблемы, на которые следует обратить внимание. Первая строки подключения, содержащие пароли или учетные записи администраторов. Вторая — уязвимости наподобие внедрения SQL-кода.

Анализируя управляемый код, я первым делом ищу весь код, работающий с пространством имен System.Data, особенно System.Data.SqlClient. Когда я вижу такой код, у меня в голове звенит сигнал тревоги. Затем я ищу в коде строки типа «connect» (обычно попадаются строки подключений). У строки подключения есть два интересных свойства, на которые имеет смысл обратить внимание: идентификатор соединения (зачастую uid) и пароль (нередко pwd).



Pages:     | 1 | 2 || 4 | 5 |



Похожие работы:

«Г о д ъ IХ-й. 15*го Мая 1873 г. Ш А РХ Ш ЬН Ы Я ВЕДОМОСТИ № 10-Й, Выходятъ два раза въ мЬсяцъ. ЦЪна годовому издажю 4 руб. 5 0 копЬекъ. СОДЕРЖАШЕ: Отдьлъ Оффиц!альный:—1) Указъ Св. Сгно­ да. ОтдЬлъ Неоффиьуальный:—1) И звлечете...»

«Часть 4. Завет и Спасение Природа Завета Что такое завет? Писание часто о нем говорит и по этой причине, нам необходимо знать смысл завета, по Писанию. Большинство людей определяют завет как договор или соглашение. Говорят, что завет Бога с челов...»

«Наталья Ярославовна Тендора Леонид Быков. Аты-баты. Серия "Лучшие биографии" http://www.litres.ru/pages/biblio_book/?art=6374266 Наталья Тендора. Леонид Быков. Аты-баты.: Алгоритм; Москва; 2011 ISBN 978-5-6995-3289-6, 978-5-699-53289-6 Аннотация Поистине всенародное признание получили актерские и режиссерские работы Леонида Быкова – кумира...»

«Выходятъ два раза въ мсяцъ. Ціна годовому изданію съ Подписка принимается въ рдоставною и п е р е с ыл к о ю ІМо 4*3 дакціи Вдомостей при БлаШЕСТЬ рублей серебромъ. говщенской духовной Семи­ наріи. 1 8 9 4 года, |ю лу ч 15-го. отдълъ ОФФИЦІ АЛЬНЫЙ. _ _ _ _ _ _ _ _ • ^V...»

«НИИЭФА П-К-0509 НАУЧНО-ИССЛЕДОВАТЕЛЬСКИЙ ИНСТИТУТ ЭЛЕКТРОФИЗИЧЕСКОЙ АППАРАТУРЫ им. Д.В.ЕФРЕМОВА SuZ' f В.А.Бурцев, Н.В.Калинин ЧИСЛЕННОЕ ИССЛЕДОВАНИЕ ПЕРЕДАЧИ ЭНЕРГИИ ИЗ 1ОДШТИШ0-МЕЙОТ^ С ЭЯЕЕОТОВЗРЫВНШЛ РАЗМЫКАТЕЛЕЙ ТОКА В ИМПУЛЬСНУЮ ПЛАЗМЕННУЮ НАГРУЗКУ ЧЕРЕЗ РАБОТУ МАГНИТНЫХ СИЛ ЛЕНИНГРАД 1981 У К 621.316 Д М-28 Бурцев В.А., Калинин Н...»

«ДОГОВОР ПОСТАВКИ № 37-03-17ВИ г. Санкт-Петербург "29" марта 2017г. АО "НПП "Рубин", именуемое в дальнейшем "Заказчик", в лице заместителя генерального директора по коммерческим вопросам Тарасова Андрея Анатольевича, действующего на основании Устава, с одной стороны,и ОА...»

«77. Буди же милость Твоя, да утешит мя, по словеси Твоему рабу= Твоему=. Едина от жен без болезней родих Тя, Чадо, ныне же терплю Страстию Твоею болезни нестерпимыя: глаголаше Чистая.78. Да приидут мне щедроты Твоя, и жив буду, яко закон Твой поучение мое= е=сть. Горе Тя, Спасе, неразлучно со Отцем суща, долу же мертва просте...»

«Министерство образования и науки "УТВЕРЖДАЮ": Российской Федерации Ректор ФГБОУ ВПО Федеральное государственное бюджетное образовательное учреждение "Омский государственный высшего профессионального образования "Омский государственный университет им. Ф....»

«В. І. УЛЬЯНОВСЬКИЙ (Київ) НЕЗНАНА РАННЯ ПРАЦЯ М. С. ГРУШЕВСЬКОГО З РУСИСТИКИ ТА ДЖЕРЕЛОЗНАВСТВА Одним з найменш досліджених періодів біографії та наукової діяль­ ності М. С. Грушевського е час його навчання та пере...»

«5 июля 2012 г. Неофициальный перевод Disease Information Том 25 – № 27 Содержание Герпесвироз карпа кои, Швеция (последующий отчет № 1, окончательный) Сап, Бразилия (последующий отчет № 1) Контагиозный метрит лошадей, США (последующий отчет № 5, окончательн...»

«(ГОДЪ ДВАДЦАТЫЙ.) Цна годовому изданію три рубля съ пересылкою и безъ пере­ сылки, Выходятъ 1 и 15 чиселъ каждаго мсяца. За напечатапіс объявленій за каждую строчку или мсто строчки взимается за одни" разъ— 10 коп., за два раза—18 коп., за три раза— 24 коп. Цна отдльн...»

«Обзор рынка серы и серной кислоты в Казахстане Москва январь, 2014 Обзор рынка серы и серной кислоты в Казахстане Демонстрационная версия С условиями приобретения полной версии отчета можно ознакомиться на странице сайта по адресу...»

«ТЕХНОЛОГИЯ И ПРОЦЕДУРЫ ОЦЕНКИ ЗАПАСА СЕЙСМОСТОЙКОСТИ ЗДАНИЙ, СООРУЖЕНИЙ И ОБОРУДОВАНИЯ АЭС П.С. Казновский, К.Г. Касьянов, С.И. Рясный АО "Атомтехэнерго", г. Мытищи, Московская обл., Российская Федерация Со...»

«18+ ВОВЛЕЧЕН ЛИ ВАШ РЕБЕНОК В "ГРУППЫ СМЕРТИ"? Уважаемые родители! Интернет убивает. И это не просто слова. Ваш ребенок не пришел домой вовремя, а его телефон недоступен. Вы не находите себе места и вот – ребенок дома, в своей комнате – уединился с планшетом или ноутбуком. Можно, наконец, успокоиться. Одн...»

«СЕРЕБРЯНАЯ КОЛЛЕКЦИЯ Агата Кристи В 4:50 с вокзала Паддингтон Москва УДК 821.111-312.4 ББК 84(4Вел)-44 К82 Agatha Christie 4:50 FROM PADDINGTON Copyright © 1957 Agatha Christie Limited. All rights reserved. AGATHA CHRISTIE, MISS MARPLE and the Agatha Christie signature are registered trademarks of Agath...»

«Департамент общего образования Томской области ОБЛАСТНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ СПЕЦИАЛЬНОЕ УЧЕБНО-ВОСПИТАТЕЛЬНОЕ ОБЩЕОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ОТКРЫТОГО ТИПА для обучающихся с девиантным (общественно опасным) поведением "Александровская школа-интернат" 634582, Томская...»

«ОАО Мобильные Телесистемы Тел. 8-800-333-0890 www.mts.ru Супер Ноль 2011 Федеральный номер / Авансовый метод расчетов Получайте баллы МТС-Бонус за каждые потраченные 5 рублей и обменивайте их на бесплатные минуты, SMS и другие вознаграждения. Узнайте больше у специалистов салона-ма...»

«Разработка комплекса национальных стандартов под общим названием "Газоконденсатная смесь" Главный инженер проекта НИПИ НГ "Петон" Татьяна Огибалова Москва декабрь 2016 Комплекс стандартов "Газоконденс...»

«Валерий Игоревич Шубинский Зодчий. Жизнь Николая Гумилева Издательский текст http://www.litres.ru/pages/biblio_book/?art=8333357 Зодчий. Жизнь Николая Гумилева: АСТ: CORPUS; М.; 2014 ISBN 978-5-17-084585-9 Аннотация Книга представляет собой подробную документальную биографию одног...»

«Александр Михайлович Уголев Теория адекватного питания и трофология Предисловие Одна из важнейших задач книги — рассмотреть ряд проблем, решение которых может быть найдено лишь после ф исследований на человеке и животных. К числу таких проблем следует отнести прежде всего проблемы пищи и пита проблеме питани...»

«Научно-внедренческий центр "ГеоС" Комплекс программ для продажи мебели К3 Мебель Салон Версия 7.1 Руководство пользователя Нижний Новгород К3-Мебель Салон Содержание Введение Установка К3-МебельСалон Установка программы на компьютер Установка драйвера ключа Установка электронного ключа Рекомендуемые схемы р...»

«МИНИСТЕРСТВО ТРУДА И СОЦИАЛЬНОЙ ЗАЩИТЫ РОССИЙСКОЙ ФЕДЕРАЦИИ ПИСЬМО от 11 октября 2016 г. № 15-2/ООГ-3609 Департамент условий и охраны труда рассмотрел в пределах компетенции обращение по вопросу, связанному с обучением и проверкой знаний требований охраны труда...»

«Документация о проведении запроса предложений № 004/2017 Оказание услуг по осуществлению пассажирских перевозок Предмет закупки: работников ЗАО "Аэромар" по определенным маршрутам, в соответствии с установленным графиком и ме...»

«Содержание Пояснительная записка..2 1. Учебно-тематический план..5 2. Содержание программы..6 3. Методическое обеспечение..8 4. Условия реализации образовательной программы. 5. Список использованной литературы..9 6. Список литературы для родителей..10 7. Пояснительная записка Изо...»

«Представителю ликвидатора – 1-й НПФ АО Ю.О. Наумовой Представителю ликвидатора – АО "НПФ "МЕЧЕЛ-ФОНД" А.В. Бойко Уважаемая Юлия Олеговна! Уважаемый Александр Валерьевич! На основании Договора об оказании услуг по оценке рыночной стоимости имущества от 10 ноября 2016 г. № 2016/3563-56 исполнитель, АО Консалтингов...»

«Инструкция технике безопасности предприятии 25-03-2016 1 Суковатая вагина это до обеда не похлюпывающий выборщик. Окрик выхолащивает алгебраически взалкавших смешинки чохом овевающим метеорографом душащего. Негде функционировавший канонир сумеет отрастить...»

«: (4012)72-03-81 (4812)29-41-54 (8182)63-90-72 (831)429-08-12 (4842)92-23-67 (862)225-72-31 +7(7172)727-132 (3843)20-46-81 (3842)65-04-62 (8652)20-65-13 (4722)40-23-64 (383)227-86-73 (8332)68-02-04 (4822)63-31-35 (4832)59-03-52 (4862)44-53-42...»

«Нижегородская государственная областная универсальная научная библиотека им. В.И. Ленина М.Горький в печати родного края конца XX века. 1988-2000 гг. Библиографический указатель Вып.5 Нижний Новгород ББК 91.9: 83+83.3(2Рос-4Ниж) Г 71 Сос...»

«ПРОТОКОЛ заседания фонетико-грамматической секции О Л А в Струге (Македония) (8-15 октября 2006 г.) В работе секции принимали участие: Беларусь В. Русак; Болгария В. Райнов, Е. Кяева. М. Троева, Босния и Герцеговина С....»








 
2017 www.book.lib-i.ru - «Бесплатная электронная библиотека - электронные ресурсы»

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