WWW.DISSERS.RU

БЕСПЛАТНАЯ ЭЛЕКТРОННАЯ БИБЛИОТЕКА

   Добро пожаловать!

Pages:     | 1 |   ...   | 8 | 9 || 11 | 12 |

«Michael Howard David LeBlank WRITING SECURE CODE Second Edition Microsoft Press ...»

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

516 Часть IV Особые вопросы // более 2000 символов 'а'

return s.ToStringf);

static void Main(string[] args) { _rand = new Random(unchecked({int)DateTime. Now. Ticks));

string CRLF = "\r\n";

try { string htmlFile = "test.html";

string prolog = "";

string epilog = @"";

StreamWriter sw = new StreamWriter{htmlFile);

sw.Write(prolog + CRLF);

string [] numericArgs = { "ForeColor", "SampleCount", "TimeBarColor", "Readonly"};

string [] stringArgs = { "LogFileName", "YAxisLabel", "XAxisLabel"};

for (int 1=0;

i < numericArgs. Length;

i++) Sw.Write(@"{2}", numericArgs[i ], getNum( ), CRLF) ;

for (int j=0;

j < stringArgs. Length;

j++) sw.Write(@"{2>", stringArgs[j],getString(),CRLF);

sw,Write(epilog + CRLF);

sw. Flush();

sw.Close();

} catch (lOException e}{ Console. Write(e.ToStringO);

.

Часть IV Особые вопросы 51 ;

После создания файл загружают в браузер, чтобы посмотреть, как ведет себя элемент управления с подставными данными, Тестирование элементов управления не ограничивается параметрами. Вы дол жны также проверить все тэги <РАКАМ>, методы, события и свойства (потому что некоторые свойства могут возвращать другие объекты, которые также подлежат полноценному тестированию).

Если применяется Microsoft Internet Explorer, необходимо проверить работу элемента управления в различных зонах;

элемент управления ведет себя по-раз ному в зависимости от зоны или домена.

Тестирование приложений, основанных на файлах Набор тестов процедур обработки файлов зависит от того, что приложение дела ет с файлом. Например, если оно создает один или несколько файлов или управ ляет ими, при планировании тестирования обратитесь за подсказкой к рис. 19-1.

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

Следующий простой сценарий на Perl создает файл FileJxt, который считывается программой Process.exe. Но сценарий «хитрит*: готовый предоставляемый при ложению файл содержит строку длиной от 0 до 32 000 символов «А», my SFILE = "file.txt";

ту $ехе = "program.exe";

ту @sizes = (0,256,512,1024,2048,32000);

foreach(@sizes) { printf "Trying $_ bytes\n";

open FILE, "> SFILE" or die "$!\n";

print FILE ' A ' x $_;

close FILE;

Я Обратите внимание на использование кавычек - как при вызове system().

'$ехе SFILE';

Если вы хотите определить, какие файлы использует приложение, рекомендую вам утилиту FileMon (http://wwifsysmternals.com), Примечание Другие инструменты, которые должны быть в вашем «ремкомп лекте» — Holodeck и Canned Heat, созданные в Центре исследования разработки ПО (Center for Software Engineering Research) в Институте технологии Флориды (Florida Institute of Technology). Подробнее — на сайте http://selit.edu/projects. Также обязательно прочитайте книгу Джеймса Уайттекера (James д. Whittaker) «How to Break Software: A Practical Guide to Testing* (Как взламывать код: практическое руководство по тестиро ванию) (см. библиографический список).

Тестирование защиты ГЛАВА Тестирование приложений, использующих данные реестра Такие приложения легко тестировать, если прибегнуть к Perl-модулю Wm32::Registry.

И на этот раз программа получилась короткой и простой. Она присваивает стро ковому параметру значение, состоящее из 1000 букв «А», после чего запускает приложение, которое считывает его.

use Win32::Registry;

my $reg;

$::HKEY_LOCAL_HACHINE->Create("SOFTWARE\\AdvWorks\\1.0\\Config",$reg) or die "$~E";

my $type = 1;

tt string my $value = ' A x 1000;

$reg->SetValueEx("SomeData","",$type,$value);

$reg->Close();

'process.exe';

Ha VBScript это выглядит так:

Set oShell = WScript.CreateObject("WScript.Shell") strReg = "HKEY_LOCAL_HACHINE\SOFTWARE\AdvWorks\1.0\Config\NumericData" dShell.RegWrite strReg, 32000, "REG_DWORD" Выполнить process.exe, 1 означает в активном окне, ' True означает: ожидать завершения приложения.

iRet = oShell.Run("process.exe", 1, True) WScript.Echo "process.exe returned " & iRet He забывайте очищать системный реестр между тестами. Если вы не знаете, к каким параметрам реестра обращается приложение, то воспользуйтесь утилитой RegMon (http://ivwwsysinternals.com).

Внимание! В принципе, можно не особо тестировать защищенные объекты — в том числе файлы или реестр на томах NTFS, — если ACL па этих объектах разрешают доступ только администраторам. Это еще один аргумент в пользу качественных списков ACL: они сокращают число тестовых сце нариев. Тем не менее в общем случае, даже если информация доступна для перезаписи только администраторам, лучше, когда, «объевшись* подложными данными, приложение «падает•> корректно.

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

my $arg= ' A ' x 1000;

'process.exe -p Sargs';

$? »= 8;

print "process.exe возвратил $?";

18- 520 Часть IV Особые вопросы Естественно, вам придется протестировать все параметры с ошибочными дан ными. И в каждом случае обязательно проверять возвращаемое значение програм мы, содержащееся в переменной ?, чтобы узнать не «упало» ли приложение. Об ратите внимание, что в действительности из процесса возвращается значение — $? »8, а не исходное $?.

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

# ExerciseArgs.pl It Подставьте свои значения, ту $ехе = "process.exe";

ту Siterations = 100;

# Возможные типы параметров, my SNUMERIC = 0;

ту SALPHANUM = 1;

ту $РАТН = 2;

# Коды всех параметров и типов:

К /р - путь, /i - числовое и /п буквенно-цифровое, my Xopts = ( р => $РАТН, i => $NUMERIC, n => IALPHANUH);

# Выполняем тесты.

for (my $i = 0 ;

$i < Siterations;

$i++) { print "Iteration $i";

и Сколько возьмем аргументов?

my $numargs = "I + int rand scalar Xopts;

print " ($numargs args) ";

в Строим массив параметров, my @opts2 = ();

foreach (keys Xopts) { push §opts2, $_;

!

ff Строим строку аргументов.

my $args = "";

for (my $j = 0;

$j < Snumargs;

$j++) { my $whicharg = ®opts2[int rand scalar @opts2];

my $type = $opts{$whicharg};

my $arg = "";

ГЛАВА 19 Тестирование защиты $arg = getTestNumeric() if Stype == $NUMEHIC;

$arg = getTestAlphaNumO if $type == $ALPHANUH;

$arg = getTestPath() if $type == SPATH;

ft Формат аргумента: /<имя>:<аргумент> tt примеры: /n:test и /п: Sargs = Sargs. " /". $whicharg. " : $ a r g " ;

' tt Вызываем приложение с аргументами.

'$ехе $args';

$? »= 8;

printf "$exe возвратил $?\п";

Я Функции обработки # Возвратить числовой результат теста;

# ЮЯ случаев результат нулевой.

и В остальных случаях это значение из диапазона -32000 - 32000.

sub getTestNumeric { return rand >. ?О : (int rand 32000) - (int rand 32000);

tt Вернуть строку произвольной длины, sub getTestAlphaNum { return 'A' x rand 32000;

\ Я Возвратить путь с именами многих каталогов разной длины, sub getTestPatn { my $path="c:\\";

for {my $i =0;

$i < rand 10;

$i++) { my $seg = 'a' x rand 24;

Spath = $path. $seg. "\\";

!

return $path;

В Windows переполнение буфера из-за параметра командной строки редко порождает серьезную дыру в защите, потому что приложение выполняется в кон тексте пользователя. Но подобное переполнение должно рассматриваться как изъян в качестве кода. В UNIX и Linux переполнения буфера командной строки пред ставляют серьезную опасность, потому пользователь root может сконфигуриро вать приложения на исполнение в контексте с более высокими привилегиями, чем базовые, для чего обычно устанавливается флаг SLID (set user ID). Таким образом Часть IV Особые вопросы переполнение буфера в приложении, настроенном для исполнения в контексте root, станет катастрофой даже при запуске благонадежным пользователем. Подоб ная брешь была обнаружена в операционных системах Solaris 2.5, 2.6, 7 и 8, со зданных корпорацией Sun Microsystems. Устанавливаемый как setuid root инстру мент \Vhodo оказался уязвим по отношению к переполнению буфера, что позво ляло взломщику получить привилегии root на компьютерах Sun (bttp://ivwwsec urityfocus.com/bid/2935}.

Тестирование полезных данных XML По мере того как данные, переносимые протоколом XML, становятся все более важными, растет значимость полного тестирования полезных данных XML. Сле дуя рекомендациям рис. 19-1, можно тестировать полезные данные XML, создавая разные тэги — слишком длинные, слишком короткие или состоящие из недействи тельных символов. Также поэкспериментируйте с объемом полезных данных XML увеличьте его или сведите практически к нулю. Наконец, уделите внимание самим данным.

«•Опасные* полезные данные моделируются с помощью Perl-модулей, классов.NET Framework или модели Microsoft XML DOM (XML Document Object Model).

Следующий пример (см. папку Secureco2\Chapterl9) строит простые полезные данные XML средствами JScript и HTML. Я использовал HTML, потому что код те стирования проще всего создать на основе XML-шаблона.

</user> </XML> созданный XML-файл, вы обнаружите, что имя и название должности представляют собой очень длинные строки, а возраст — случайное число. Вы можете создать очень большие XML-файлы, содержащие тысячи объектов.</p><p> Если в процессе тестирования потребуется направить XML-файл в Web-сервис, советую воспользоваться объектом XMLHTTP, Вместо того чтобы сохранять XV L данные в файл, отправьте их в Web-сервис таким образом:</p><p> var оНТТР = new ActlveXObjectC'Microsoft. XMLHTTP");</p><p> oHTTP.OpenC'PQST", "http://local.hosl:/ PostData.htm", false);</p><p> оНТТР. send(user.XMLDocument);</p><p> Создавать полезные данные XML средствами.NET Framework очень просто.</p><p> Следующая программа на С# создает большой XML-файл подложных данных.</p><p> Имейте в виду, что реализацию функций getBogusISBN и getBogusDate я оставляю вам в качестве упражнения!</p><p> static void Main(string[] args) { string file = @"c:\1.xml";</p><p> XmlTextWriter x = new XmlTextWriter(file, Encoding. ASCII);</p><p> Build(ref x);</p><p> // Выполняем какие-то операции с XML-файлом, static void Build(ref XmlTextWriter x) { x. Indentation = 2;</p><p> x. Formatting = Formatting. Indented;</p><p> x.WriteStartDocument(trije);</p><p> x. WriteStart Element ( "books", "" ) ;</p><p> for (int i = 0;</p><p> i < new Random. Next{1000);</p><p> i++) { string s = new String('a', new Random(). Next(IOOOO));</p><p> x. WriteStart Element ("book", "");</p><p> x.WriteAttributeString("isbn", getBogusISBNQ);</p><p> x.WriteElementString( "title", "", s);</p><p> x.WriteElementStringC'pubdate", "", getBogusDateO);</p><p> x. WriteElementString{ "pages", "", s);</p><p> x.WriteEndElementO;</p><p> \ x.WriteEndElementO;</p><p> x. WriteEndDocument( ) ;</p><p> x.CloseC);</p><p> 524 Часть IV Особые вопросы Некоторые специалисты считают, что XML приведет к появлению нового по коления опасностей для защиты, особенно если XML будет содержать сценарии, Я думаю, что об этом пока рано судить, но вы уж позаботьтесь, чтобы ваши при ложения на основе XML были качественно написаны и безопасны — так, на вся кий случай! Один из взглядов на эту проблему изложен на странице http://wunu.com puteru>orld.com/rckey2 59/story/0,1199№V63_STO6l 979,00 Ыт1.</p><p> Тестирование SOAP-сервисов По существу, SOAP-сервис тестируется по тем же принципам, что XML и HTTP, ведь SOAP это не что иное, как XML поверх HTTP! Следующий пример на Peri (в папке Secureco2\Chapterl9) демонстрирует, как создавать «вредные» SOAP-запросы для атаки на ничего не подозревающий SOAP-сервис.</p><p> Примечание SOAP может передаваться и по другим транспортным протоко лам, в том числе поверх SMTP и через очереди сообщений, но HTTP применяется в подавляющем большинстве случаев.</p><p> # TestSoap. pi use HTTP::flequest::Common qw(POST);</p><p> use LWP::UserAgent;</p><p> ray $ua = LWP::UserAgent->new();</p><p> $ua->agent("SQAPWhack/1.0");</p><p> my $url = 1http://localhost/MySOAPHandler.dll1;</p><p> my Site rations = 10;</p><p> # Используется в coinToss my $HEADS = 0;</p><p> my $TAILS = 1;</p><p> open LOGFILE, "»SOAPWhack. log" or die $!;</p><p> tt Некоторые операции SOAP It не забудьте добавить свои операции и, конечно же, "мусор"!</p><p> my @soapActions=('','Junk1,'foo.sdl');</p><p> for (my $i = 1;</p><p> $i <= $iterations;</p><p> $i++) { print "SOAPWhack: $i of $iterations\r";</p><p> tf Выбираем случайную операция.</p><p> ту SsoapAction = $soapActtons[int rand scalar @soapActions];</p><p> tsoapAction = 'S' x int rand 256 if SsoapAction eq 'Junk*;</p><p> my SsoapNamespace = "http://schemas.xinlsoap.org/soap/envelope/";</p><p> my Sschemalnstance = "http://www.w3.org/2001/XMLSchema-instance";</p><p> my $xsd = "http://www.w3.org/XHLSchema";</p><p> my JsoapEncoding = "http://schemas.xmlsoap.org/soap/encoding/";</p><p> ГЛАВА 19 Тестирование защиты my $spaces = coinToss() == SHEADS ? ' ' : ' ' х int rand 16384;</p><p> my Serif = coinTossO == $HEADS ? ' \ n ' : '\n' x int rand 256;</p><p> H Выполняем SOAP-запрос.</p><p> my SsoapRequest = POST $url;</p><p> SsoapRequest- >push_header("SOAPAction" => SsoapAction);</p><p> $soapRequest->content_type('text/xml');</p><p> $soapRequest->content("<soap;</p><p>Envelope ". $spaces.</p><p> xmlns:soap=\"". $soapNamespace.</p><p> "\" xmlns:xsi=\"". Sschemalnstance.</p><p> "\" xmlns:xsd=\"". $xsd.</p><p> "\" xmlns:soapenc=\"". SsoapEncoding.</p><p> "\"><soap:Body>". Serif.</p><p> "</soap: BodyX/soap: Envelope>">;</p><p> Я Выполняем запрос, ray SsoapResponse = $ua->request($soapRequest);</p><p> П Сохраняем в журнале информацию о результатах.</p><p> print LOGFILE "[SOAP Request]";</p><p> print LOGFILE $soapRequest->as_string. "\n";</p><p> print LOGFILE "[WSDL response]";</p><p> print LOGFILE $soapResponse->status_line. " ";</p><p> print LOGFILE $soapResponse->as_string. "\n";</p><p> close LOGFILE;</p><p> sub coinToss { return rand 10 > 5 ? $HEADS : $TAILS;</p><p> \ He забудьте применить различные методы мутации, описанные ранее в этой главе, Наконец, для создания многопоточных инструментов тестирования вы впра ве задействовать класс SoapHttpClientProtocol каркаса.NET Framework.</p><p> Тестирование на предмет атак с использованием кросс-сайтовых сценариев и внедрения кода сценариев В главе 13 мы обсудили атаки с применением кросс-сайтовых сценариев (cross site scripting, XSS) и опасности принятия данных, вводимых пользователем. А сейчас вы узнаете, как проверить уязвимость вашего Web-приложения для атак с при менением сценариев. Методы, о которых сейчас пойдет речь, не охватывают все виды подобных атак, поэтому при создании тестовых сценариев рекомендую обратиться к главе 13 за сведениями о других видах атак. Сложность тестирова ния на предмет наличия XSS-брешей отличается для разных их типов: одни тес тировать проще, другие — сложнее.</p><p> Особые вопросы 526 Часть IV Примечание Прекрасный источник информации о XSS-дефектах приложе ний — сайт http://www.owasp.org.</p><p> Если вы поняли, что причина XSS — в отображении вводимой пользователем информации, — то быстро поймете, как их тестировать: «скармливать* Web-при ложению строки ввода. Прежде всего выявите все точки ввода в Web-приложение — поля, заголовки (включая cookie-файлы) и строки запросов. Затем заполните все входные строки константами и отправьте запрос на сервер. Наконец, проверьте HTTP-ответ, не возвращена ли строка пользователю. Если она отображается на экране в неизменном виде, высока вероятность, что приложение уязвимо для XSS атак и нуждается в коррекции. Способы лечения подобных «болезней* описаны в главе 13 Заметьте: положительный результат подобной проверки не обязательно означает, что приложение уязвимо для XSS-атак, а лишь то, что необходим более глубокий анализ. Также, если во входной строке есть специальные символы, на пример <>>, а в ответной строке их нет, следовательно, Web-страница выпол няет определенную XSS-фильтрацию. Теперь можете приступать к проверке на личия ошибок в коде обработки.</p><p> Совет Иногда приходится добавлять во входные данные один или несколько переводов каретки или строки [метасимволы (Срт)] — некоторые Web сайты анализируют только первую строку входной информации, Следующий сценарий на Perl создает входные данные для формы и ищет воз вращенный текст. Если выходные данные содержат введенный текст, страницу придется исследовать более пристально, так как весьма вероятно, что она уязви ма для XSS. Сценарий выполняет еще одну операцию: проверяет, выполняется ли какая-либо XSS-обработка на сервере. Имейте в виду, что этот код не обнаружит все бреши. XSS-дыра может не проявиться в результирующей странице, а лишь на одной из следующих. Поэтому тестировать приложение придется особо тщательно.</p><p> » CSSInject.pl use HTTP::Request::Common qw(POST GET);</p><p> use LWP::UserAgent;</p><p> my $url = "http://127.0.0.1/test.asp";</p><p> my $css = "xyzzy";</p><p> $_ = buildAndSendRequest($url,$css);</p><p> » Если внедренный код обнаруживается в отклике, возможны проблемы, if (indexflc $_, 1с $css) != -1) { print "Possible XSS issue in $url\n";</p><p> ft Копаем глубже my $css = "<>></p><p>";</p><p> $_ = buildAndSendRequest($url, $css);</p><p> if (index(lc $_, Ic $css) != -1) { print "Похоже, никакой XSS-обработки не выполняется в $url\n";</p><p> } else { ГЛАВА 19 Тестирование защиты print "Похоже, какая-то XSS-обработка поддерживается в $url\n";</p><p> } I sub buildAndSendRequest { my ($url, $css) = @_;</p><p> ff Создаем строку клиента.</p><p> my $ua = LWP::UserAgent->new();</p><p> fl Конструируем запрос.</p><p> $ua->agent("CSSInJect/v1.42 WindowsXP"};</p><p> my $req = POST $url, [Name => $css, Address => $css, Zip => $css];</p><p> my $res = $ua->request($req);</p><p> return $res->as_string;</p><p> i Текст этого примера есть в папке Secureco2\Chapterl9 Примечание Некоторые бреши из тех, что упомянуты в статье «Malicious HTML Tags Embedded in Client Web Requests* (Опасные HTML-тэги, внедренные в клиентские Web-запросы) на странице http://twuw.certjorg/advisories/CA 2000-02.html, удалось бы обнаружить подобным тестировочным кодом.</p><p> Тестирование клиентов с применением подставных серверов До сих пор я основное внимание уделял сценариям атак на сервер. Не менее важ но выполнять нагрузочное тестирование клиентских приложений подставными серверами. Первый способ — создать специальную тестовую версию сервиса, которая отправляет пользователю недействительные данные. Только не шлите эту версию своим клиентам! Второй способ — создать особые серверные приложе ния, которые отвечают на запросы пользователей особо изобретательно и зло намеренно. Самый простой случай: принимая запросы от пользователей, сервер в ответ отправляет откровенный <• мусор». Далее приводится пример сервера (см. папку Secureco2\Cbapterl9~), принимающего любые запросы на порт 80 от любых пользователей, и отправляющий в ответ случайные наборы байт. Приложив не много стараний, вы сможете заставить сервер отвечать неверными, но тем не менее очень похожими на корректные данными.</p><p> ft TCPJunkServer.pl use 10:rSocket;</p><p> my $port = 80;</p><p> my {server = 10::Socket:;</p><p>INET->new(LocalPort => Sport, Type => SOCK_STREAM, Особые вопросы 528 Часть IV Reuse => 1, Listen => 100) or die "He удается открыть порт $port: $@\n";</p><p> while (Sclient = $server->accept( }) { my Speerip = $client->peerhost();</p><p> my $peerport = $client->peerport();</p><p> my $size = tnt rand 16384;</p><p> my (Sonars = ( ' A '.. ' Z ', ' a '.. ' z ', 0.. 9, qw( I e tf $ X " & * - + = ) ) ;</p><p> my $junk = join ("", §chars[ map{rand @chars } (1.. $size)]);</p><p> print "Подключение с $peerip:$peerport, ";</p><p> print "отправка $size байт мусорных данных. \п";</p><p> $client->send($junk);</p><p> closeCSserver);</p><p> Разрешено ли пользователю видеть и/или изменять данные Полезно протестировать приложение на предмет доступа к данным и риска рас крытия информации. Сможет ли взломщик изменить или просмотреть данные.</p><p> защищаемые приложением? Например, если интерфейс доступен только админи стратору, то все остальные пользовательские учетные записи при попытке досту па получат ошибку Самый простой способ выяснить, так ли это, — создать сце нарий, аналогичный предыдущим, но запросы должны быть корректными. Ника ких подложных или некорректных данных! Далее следует войти обязательно под учетной записью обычного пользователя (не администратора) или открыть до полнительную консоль входа в систему командой RunAs и войти как пользователь.</p><p> а затем попытаться из сценариев получить доступ к интерфейсам или данным. По лучение ошибки доступа свидетельствует о том, что интерфейс ведет себя как надо, К сожалению, многие тестировщики не выполняют подобное тестирование под учетной записью обычных пользователей, а только под административной. В последнем случае тестируемые функции не сбоят из-за ограничений безопасно сти. Но ведь вся суть тестирования защиты именно в этом: убедиться, что доступ рядовому пользователю надежно закрыт!</p><p> Все ошибки, перечисленные в статьях «Available for 'Registry Permissions' Vulne rability* (http://ivww.microsoft.com/tecbnet/security/bulletm/MSOO-095.cisp} и «Offload ModExpo Registry Permissions Vulnerability* (bttp;</p><p>//wufw.microsofl.com/tecbnet/secunty/ bulletm/MSOO-024.asp"), удалось бы обнаружить, если бы тестировщики применя ли только что описанные методы, ГЛАВА 19 Тестирование защиты Тестирование с шаблонами безопасности Windows 2000 и последующие ОС поставляются с готовыми шаблонами безопас ности, в которых определены рекомендуемые конфигурации политики блокировки компьютера. Они более безопасны, чем параметры по умолчанию. Во многих компаниях эти политики устанавливают из соображений экономии средств и времени на поддержку пользовательских компьютеров;</p><p> пользователям запреща ется конфигурировать большинство компонентов системы. Часто, ковыряясь в своей системе, новички выводят свои компьютеры из строя, а восстановление конфигурации отнимает массу времени у отдела поддержки, Внимание! Если приложение поддерживает разные параметры безопасности, следует протестировать все их комбинации.</p><p> У шаблонов есть недостаток: некоторые приложения отказываются правиль но работать, если параметры безопасности отличаются от значений по умолча нию. Поскольку очень многие клиенты устанавливают политики, вы, как тести ровщик. должны проверить все конфигурации и выяснить, при каких приложе ние работает.</p><p> В табл. 19-5 перечислены шаблоны, поставляемые в составе Windows 2000 и последующих ОС.</p><p> Таблица 19-5. Шаблоны безопасности в Windows Шаблон Описание Шаблон применяет разрешения по умолчанию к группе compatws Users (Пользователи), что обеспечивает корректную работу большинства унаследованных приложений. Предполагается, что выполнена установка ОС «с нуля» и списков ACL реестра на разделе NTFS. Шаблон оставляет списки ACL для члено>;</p><p> группы Users и удаляет записи, соответствующие группе Power Users (Опытные пользователи) Шаблон предполагает, что выполнена установка ОС «с нуля» bisecdc и списков ACL реестра на разделе NTFS. Он содержит парь метры securedc (см. ниже) с присущими только Windows 2000 расширениями. Удаляет всех пользователей из группы Power Users (Опытные пользователи) Шаблон предлагает повышенную безопасность по сравне bisecws нию с securews. Ограничивает разрешения в ACL для групп Power User и Terminal Server Users (Пользователи сервера терминалов) и удаляет всех пользователей из группы Power Users (Опытные пользователи) Шаблон применяет безопасные списки ACL от корня разде rootsec ла начальной загрузки и вниз по иерархии Шаблон предполагает, что выполнена установка ОС *с нуля*, securedc а затем устанавливает надежные списки ACL реестра и в NTFS Шаблон предполагает, что выполнена установка ОС «с нуля», securews а затем устанавливает надежные списки ACL в реестре и NTFS. Удаляет всех пользователей из группы Power Users (Опытные пользователи) Шаблон содержит параметры по умолчанию, определяемые шаблон по умолчанию при установке ОС Особые вопросы 530 Часть IV Как минимум, следует сконфигурировать один или больше тестовых компью теров с шаблоном securews, если это клиентское приложение, и с шаблоном securedc, если серверное. Политика на локальном тестовом компьютере определяется в командной строке командой:</p><p> secedit /configure /cfg securews.inf /db securews.sdb /overwrite Применив шаблон, подвергните приложение всему набору функциональных тестов, чтобы проверить, не «падает» ли оно в новых условиях. Если да, то обра титесь к инструкциям в главе 7, зарегистрируйте ошибку и позаботьтесь об ис правлении недостатка.</p><p> Примечание Учтите, что компьютер с установленной политикой hisecdc или bisecws может поддерживать связь только с машинами, на которых так же определена hisecdc или bisecws. Эти шаблоны требуют подписи SMB пакетов (Server Message Block). Если другой компьютер не поддержива ет подписание 8MB, весь SMB-трафик отвергается.</p><p> Обнаружением ошибки работа не заканчивается!</p><p> Допустим, тестирование обнаружило дефект. Значит ли это, что можно поздра вить себя с качественно проделанной работой и перейти к другим тест-планам?</p><p> Нет. Необходимо поискать другие разновидности обнаруженной ошибки. Иног да это дает прекрасные результаты. Вот простой пример. Приложение принима ет текстовые IP-адреса (вида 172.100.84.22), и тестирование показало переполне ние буфера, если первый октет представляет собой не номер, а длинную строку (вида аааааааааааааааааааа.100.84.22). При таком дефекте высока вероятность, что аналогично ведут себя и другие октеты. Следовательно, вы должны изменить тес товый КОД, ЧТОбы ВВОДИЛИСЬ СТрОКИ:</p><p> аааааааааааааааааааа.100.84. 172.аааааааааааааааааааа.84. 172.100.аааааааааааааааааааа. 172.100.84,аааааааааааааааааааа Вот какова последовательность подобного анализа.</p><p> 1. Локализуйте атаку. Какие из приводящих к ошибке обстоятельств можно безболезненно удалить из тест-плана? Избавьтесь от них и создайте «сухой» exploit. В предыдущем примере IP-адрес способен входить в другую структуру данных, которая никак не связана с возникновением ошибки. Причина толь ко в IP-адресе.</p><p> 2. Выделите основные переменные exploit-программы. Выясните, какие из них могут изменяться, создавая новые разновидности атаки. Обычно это не сложно. В нашем примере это четыре октета IP-адреса.</p><p> 3. Определите возможные значимые отличительные значения. Трудно выделить значения, которые действительно значимы и являются причиной уязвимости. Важные значения переменных, используемые в exploit, обычно редко применяются и недостаточно детально задокументированы. Не бойтесь ГЛАВА 19 Тестирование защиты потратить время на выявление всех важных значений переменных. В идеале следует предусмотреть анализ существующей документации и исходного кода, а также собеседование с разработчиками, Нет ни одной пары дефектов, у которых наборы эксплуатируемых перемен ных и их значения в точности совпадают. Однако у многих exploit-программ часть переменных обычно совпадает, а это означает, что наборы их значений удастся сохранить и повторно использовать для других тестов. В предыдущем примере оказалось, что любая длинная строка в октете вызывает отказ. Дчя определения действительных и недействительные типов переменных обрати тесь к рис. 19-1.</p><p> 4. Проверьте все комбинации переменных и их значений. После тщател ь ного определения всех переменных и значений вы получите все, что необхо димо для создания тех вариантов тестов, которые пока не охвачены существу ющими сценариями тестирования, Это усложняет тестировочный код, но лю бой код — даже для поверхностного тестирования — должен быть высокока чественным. Об этом сейчас и поговорим.</p><p> Тестировочный код должен быть высококачественным Меня тошнит от одних и тех же комментариев типа: «Фу, да ведь это всего лишь тестировочный код*. Плохой тест равноценен отсутствию тестирования, или хуже того — он создает ложную и опасную иллюзию отсутствия у продукта недостгт ков. Мне вспоминается один дефект, который остался в продукте из-за того, ч го при выполнении сценария тестирования приложение тихо «умирало* из-за ошибки в подсистеме безопасности. При каждом прогоне приложение «падало», но тес тировочному коду не удавалось перехватить исключение, инициированное при ложением, и он продолжал проверку как ни в чем не бывало, Тестировочный код следует писать так же качественно, как и сам продукт, чтобы не краснеть перед клиентом. А ведь очень часто тестировочный код передают сторонним разработчикам, которые создают расширения к вашему приложению, командам разработчиков и сотрудникам партнерских фирм, которые будут зани маться обновлением и сопровождением текущей версии, и др.</p><noindex> <div class="reklama"> <center> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- dislib-kvadrat (text1) --> <ins class="adsbygoogle" style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-9894471784993021" data-ad-slot="8516509936"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </center> </div> </noindex> <p> Сквозное тестирование решения Когда речь идет о создании безопасных распределенных приложений, ни одну технологию или функцию нельзя рассматривать в отрыве от остальных частей, ведь решение — это сумма его составляющих. Даже самый детальный и тщатель но продуманный проект небезопасен, если хотя бы одна его часть слаба. Как "е стировщик, вы должны последовательно находить слабые звенья и добиваться их укрепления или устранения.</p><p> Совет Имейте в виду, что иногда собранные вместе несколько сравнительно безопасных компонентов становятся опасными!</p><p> 532 Часть IV Особые вопросы Определение «поверхности поражения» Люди любят числа, особенно когда это оценки. Кажется, мы находим утешение в цифрах сравнения. Я уже потерял счет, сколько раз меня спрашивали;</p><p> «Насколь ко продукт А безопаснее, чем В?» К сожалению, ответить практически невозмож но, да мы и пытаться не станем. А поговорим о том, как определить, сколько ком понентов приложения уязвимы для атак. Процедура проста.</p><p> 1. Определите основные векторы атаки, 2. Определите модули этих векторов, 3. Сосчитайте число векторов с ненулевыми модулями в продукте.</p><p> В результате вычисляется так называемый относительный индекс поверхнос ти поражения (relative attack surface quotient, RASQ). Давайте детальнее познако мимся с этим, Определите основные векторы атаки Обычно существует несколько «каналов* атаки на приложение. Например, все операционные системы атакуют через сокеты, Windows-системы — через слабые списки ACL, Linux и UNIX-сервера — с применением setuid-приложений, испол няемых под учетной записью root, а серверы базы данных — через хранимые процедуры. Попробуйте определить, как взломщики станут атаковать ваши при ложения. Эта информация — как вы уже догадались — должна поступать из моде лей опасностей!</p><p> Определите модули векторов атаки Далее определите, насколько серьезны возможные последствия атаки по различ ным векторам. Например, сокеты относятся к самым уязвимым компонентам ОС и практически всегда подвергаются нападению, а вот «слабые» списки ACL атаку ют реже, да и последствия успешной атаки редко бывают катастрофическими.</p><p> Модуль вектора показывает степень опасности атаки.</p><p> Определите число векторов с модулями Наконец, необходимо сосчитать векторы атаки в приложении и указать их моду ли, чтобы получить значение RASQ. В качестве примера приведу анализ ОС Win dows (табл. 19-6).</p><p> Таблица 19-6. Векторы атаки в Windows Вектор Модуль Вектор Модуль Открытые сокеты.Активные ISAPI-фильтры 1,0 1, Открытые конечные точки RPC Динамические Web-страницы ' •I Открытые именованные каналы Виртуальные каталоги с исполняемыми файлами Службы Активные учетные записи 0' :' Службы, включенные Активные учетные записи 0, :.' по умолчанию в группе администраторов ГЛАВА 19 Тестирование защиты Таблица 19-6. (окончание} Вектор Модуль Вектор Модул!</p><p> Службы, работающие Нулевые сеансы с каналами 0, 0, в контексте SYSTEM и общими ресурсами Активные Web-обработчики Разрешенная гостевая учетная 0, I."</p><p> запись (Guest) ' о;</p><p> Слабые списки ACL Слабые списки ACL в реестре 0, в файловой системе Слабые списки ACL общих 0, ресурсов Результат сравнения различных версий Windows по этому методу показан на рис. 19-4.</p><p> „ „ — ™ — — —— — 300 250 - — r—^—^— — 200 150 100 - — — 50 Windows 2000 Windows.NET Windows.NET Windows XP Windows XP Server Server с включенным с сервером IIS брандмауэром ICF Рис. 19-4. Сравнение относительной «поверхности поражения»различных версий Windows Вы должны знать, что этот метод не годится для сравнения различных типов ОС, потому что каждая атакуется по-разному и модули векторов отличаются (но вполне годится для сравнения похожих ОС). Скажем, сравнивать Linux и OS/ бессмысленно.</p><p> Как тестировщик вы можете таким образом выяснить, сократилось ли число точек нападения по сравнению с предыдущей версией. Полезно и разумно при менять RASQ: уменьшение этого индекса от версии к версии свидетельствует об улучшении программного продукта. Разработчики вправе добавить массу новых функций, но только при условии одновременного сокращения RASQ, скажем, на i%, Наконец, это метод несколько напоминает балльную функциональную оценку (function point analysis) защиты. Он не без недостатков и ничего не говорит о качестве кода, однако в любом случае полезен, Особые вопросы 534 Часть IV Резюме Из этой главы вы узнали о роли тестировщика защиты и о его основной задаче.</p><p> Она заключается не в доказательстве нормальной работы функций, а в том, что бы заставить их делать то, что не предусмотрено разработчиками. Модель опас ностей применяется для определения компонентов приложения, которые следу ет тестировать, а также помогает выяснить, как атаковать компоненты приложе ния;</p><p> используйте классификацию STRIDE в процессе тестирования защиты от той или иной атаки.</p><p> Мутация данных — исключительно полезный способ спровоцировать сбой приложения. Стоит создать программы мутации данных и применять их для мо делирования атак на интерфейсы приложения.</p><p> Наконец, уровень уязвимости приложения для атаки определяется путем оценки «поверхности поражения». Позаботьтесь о том, чтоб подобная оценка стала пол ноправной частью процесса разработки — это позволит легко контролировать насколько безопаснее становится приложение от версии к версии, ГЛАВА Анализ безопасности кода Г~1а первый взгляд кажется, что анализ безопасности кода сродни ординарному анализу, в ходе которого выявляются обычные ошибки, вроде забытого освобож дения распределенной памяти или разыменования плохого указателя. Однако при анализе защиты ошибкам некоторых типов следует уделять особое внимание, Надежный код, как правило, достаточно безопасен, естественно, при условии от сутствия ошибок на более высоком уровне — в проекте приложения. (Например, абсолютно корректная реализация telnet пересылает имя пользователя и пароль открытым текстом.) Аккуратные, дотошные программисты, как правило, допуска ют очень мало ошибок. Самые ответственные программисты понимают, что пол ностью избежать ошибок невозможно и поэтому настаивают на доскональной проверке своего кода. Доказано, что хороший эксперт способен выявить большую часть ошибок реализации во вверенном ему фрагменте кода.</p><p> Еще лучше, если процесс анализа кода формализован. Джек Ганссл (Jack Ganssle) в своей статье «A Guide to Code Inspections* (Руководство по проверке кода) (btip. // wwwganssle.com/Inspecttons.pdf) описывает, как организовать формальный проце,:с анализа кода. Хотя в статье акцент сделан на встроенные системы, ошибки в ко торых гораздо труднее устранять, основные идеи небезынтересны. Стоит поду мать о применении этого подхода к наиболее рискованным компонентам — се тевым интерфейсам или программам, работающим в контексте высокопривиле гированной учетной записи. Если вам кажется, что доскональная проверка кода потребует уйму времени, то знайте: согласно исследованиям, устранение ошибки на этом этапе экономит 9 часов, которые ушли бы на тестирование, отладку и внесение исправлений в код. Анализ кода в 20-30 раз эффективнее для обнару жения ошибок, чем обычное тестирование, Так что же представляет собой формальный процесс анализа кода? Кроме эк сперта (reviewer) требуются еще четверо: координатор (moderator), читатель (reader), регистратор (recorder) и автор (author). Координатор управляет работой Особые вопросы 536 Часть IV группы и отслеживает найденные ошибки. Читатель описывает понятным языком ход выполнения программы. Эту роль ни в коем случае не должен выполнять ав тор, поскольку автор часто воспринимает желаемое за действительное: полагает ся на то, что должна, а не реально делает, программа. Регистратор тщательно фик сирует все найденные ошибки, что позволяет остальным участникам команды скон центрироваться на коде. Задача автора — понять обнаруженные ошибки и опи сать места, вызывающие сомнения. Анализ ни в коем случае не должен превра щаться в критику того, кто написал этот код. а затрагивать исключительно сам код. Несмотря на соблазн уменьшить число вовлеченных людей, доказано, что чет веро — оптимальная команда, причем се сокращение даже на одного значитель но снижает эффективность. Конечно, чем больше команда, тем меньше ошибок ускользнет от ее внимания, однако на их обнаружение уйдет больше человеко часов. Встроенные системы, как правило, содержат меньше кода, зато он весь жизненно важен. Кроме того, большие группы «расползаются»: ее члены переклю чаются на не имеющие отношения к делу проблемы, так что жестко контроли руйте размер группы.</p><p> Одна из наиболее важных сторон анализа безопасности кода — понимание вызываемых функций и знание специфических типов ошибок, которые приво дят к возникновению дыр в защите. Например, я не слишком много работал с RPC, поэтому считаю себя не самым лучшим кандидатом на роль эксперта, проверяю щего вызовы RFC-функций. Однако я отлично знаю сокеты. Пусть код анализиру ет тот, кто хорошо разбирается в конкретной области. Это одна из характерных ошибок, связанных с применением теории <• множества глаз»: даже если код про верит миллион людей, но ни один из них в силу незнания специфики не увидит ошибок, легче вам от этого не станет. Если вам предстоит писать код. а вы не знакомы с данной функциональной областью, посмотрите, не посвящена ли ей одна из глав этой книги, и если да, то прочитайте ее. В противном случае будьте готовы к тому что дело пойдет очень медленно, и вам придется читать докумен тацию по каждой API-функции. Уделите особое внимание разделу примечаний: там, как правило, детально разъясняется, как не попасть в ту или иную ловушку и не стать жертвой заблуждения.</p><p> Просматривая чей-то код, особое внимание обращайте на неявные допущения в функциях. Можно ли доверять вызывающей стороне в плане размера выделен ного ей и переданного буфера? Легко ли использовать данную функцию? Нужно ли вызывающему знать особенности ее реализации? Если вы попросите кого-ни будь рассказать, как работает приложение, он поневоле «заразит* вас своими до пущениями. Поэтому лучше всего читать код самому и по ходу задавать вопросы автору. Подвергайте сомнению каждое предположение — всегда считайте, что функцию вызывает враждебная программа, подконтрольная хакеру, который спит и видит, как бы нанести урон побольше. Если все пойдет не так, то насколько корректно «умрет* приложение? Если разработчик полностью доверяет входным данным, сразу поинтересуйтесь — почему? Что позволяет считать данные доверен ными и безопасными?</p><p> ГЛАВА 20 Анализ безопасности кода Быстрая взаимная проверка Есть менее тщательный, но все же приемлемый способ анализа кода. Посади те двух разработчиков за соседние компьютеры и поручите им проверять код друг друга. Они смогут задавать друг другу вопросы и проверять допущения.</p><p> Как быть с большими приложениями Допустим, один из разработчиков покинул компанию и поселился в палатке где то подальше от цивилизации. А вам досталось в наследство 250 000 строк кода, которые вы раньше в глаза не видели. Хуже всего то, что начальство требует, что бы не позднее чем через месяц был проведен анализ его безопасности. Не спе шите, ужаснувшись, хватать палатку и тоже бежать от цивилизации — выход есть.</p><p> Первое — расставьте приоритеты, так как не весь код одинаково важен и под вержен риску. Разобравшись в том, как приложение вообще работает, обратитесь к модели опасностей и диаграммам потоков данных. Они укажут на наиболее критичные с точки зрения безопасности части приложения. Все, что имеет дело с вводимыми пользователями данными, осуществляет передачу между контекста ми пользователей или предоставляет интерфейсы через сеть, требует особо тща тельной проверки. Особое внимание уделите коду, которые «издревле» славится своей уязвимостью.</p><p> Упорядочив части приложения в соответствии с риском, выполните аудит каж дой части. Особо рискованные области требуют детального, построчного анали за, желательно в рамках жестко формализованной процедуры. Менее опасные стоит анализировать более поверхностно, а наименее рискованные достаточно проье рить и вовсе только на предмет вызова потенциально опасных функций, Анализируя код, оцените общее его качество — некоторые участки вообще придется переписать. Однажды мне довелось иметь дело с одной относительно простой функцией, написанной очень «зеленым» программистом. Качество было так плохо, что даже после пересмотра опытными ребятами (и исправления мно гих ошибок) он оставался практически неисчерпаемым источником сообщений об ошибках. Я сам неоднократно пытался устранить все проблемы, но «жуки» продолжали лезть из всех дыр. В конце концов я плюнул, остался подольше на работе и полностью переписал эту функцию, а за ней еще пару-тройку других «шедевров* того же автора. Насколько мне известно, в этом модуле ошибок боль ше не возникало вообще. Написание надежных функций потребовало значитель но меньше времени, чем исправление плохих. Точно так же, если перед вами фун кция из 1 200 строк с огромными сложными циклами и вы не хотите, чтобы ос тыли ваши спагетти и чесночные тосты, может, быстрее ее просто переписать?</p><p> Во время кампании Windows Security Push в начале 2002 года, мы обнаружили несколько мест, насчет которых было принято решение попросить авторов ис пользовать другие библиотеки и удалить то, что слишком сложно довести до ума.</p><p> Повторюсь: иногда гораздо проще переписать плохой код, чем исправить суще ствующий. Есть только одна причина не заменять код — необходимость гораздо более пристального тестирования;</p><p> иногда оказывается, что тестировщики и спе Часть IV Особые вопросы циалисты поддержки уже набили достаточно шишек и в состоянии «на лету» вы чистить код от прекрасно известных им «бяк>.</p><p> Многократный проход Один из лучших экспертов по анализу кода в Microsoft активно пропагандирует многократный проход по коду. Начинать предлагается с высокоуровневого ана лиза: понять среду, исследовать структуры данных и процесс инициализации. Затем следует построить модель кода и разобраться в связях между функциями. Все уча стки кода, показавшиеся сложными, должны быть специально помечены как тре бующие особого внимания. Наконец, определите отправные точки для трассировки кода. Их устанавливают так, чтобы получить ответы на конкретные вопросы, на пример: «Может ли строка пароля переполнить буфер?» Это позволит анализиро вать проблемы по одной, а не все скопом.</p><p> Внимание! Набор слайдов, на основании которого написан этот раздел, со держит две выдержки, которые должны стать вашим девизом: «Любой код, который кажется чересчур сложным, скорее всего содержит ошибки» и «•Даже если код написан изначально корректно, последующие исправле ния могут породить ошибки».</p><p> Закончив подготовительную работе займитесь исследованием и трассировкой отправных точек. Если отправная точка начинает слишком сильно ветвиться, со здайте новую отправную точку, но не отвлекайтесь от начальной задачи. Теперь пора проверить код от функции к функции. Некоторые известные ошибки совер шают большинство программистов, постарайтесь обнаружить типовые ошибки, характерные для отдельных программистов. Проверяйте редко исполняемый код особенно тщательно, поскольку он, как правило, хуже всего тестируется, — в та ких «темных чуланах» часто таятся ошибки защиты.</p><p> Низко висящие плоды Прежде всего выполните проверку на наличие ненадежных функций, достаточно полный их список приведен в приложении А. Обратите особое внимание на фун кции обработки строк, даже если они вызываются из надежных библиотек. Вспом ните, что причиной ошибки занижения размера буфера на единицу (глава 5) была strncpy, по не strcpy. Исследуйте каждую из них и выясните, что произойдет, когда переданный указатель указывает на NULL, в переданной строке отсутствует завер шающий нуль или вызывающий процесс указал неверную длину строки. Затем поищите ошибки занижения размера буфера на единицу;</p><p> они среди наиболее часто встречающихся при попытках реализовать безопасную обработку строк. Если используются классические функции обработки строк, проверьте на завершение нулем сразу после выхода из функции — strncpy, strncat и snprint/не гарантируют завершения строки нулем. Не забудьте об ошибках, связанных с укорачиванием строк. После традиционных «безопасных» функций порой сложно определить, обрезана ли входная строка.</p><p> ГЛАВА 20 Анализ безопасности кода Буферы любых типов следует проверять очень внимательно;</p><p> проверку- на вы ход за границы проводите при каждом обращении к массиву. Эксплуатирова гь можно переполнение любого типа буфера, не только строкового. Надеюсь, при меры из главы 5 продемонстрировали, что переполнение кучи опасно ничуть TIC меньше переполнения буфера в стеке. Еще одна проблема с кучей, которая,че связана с другими типами переполнения, в том, что двукратное освобождение памяти иногда создает условия для создания успешно работающего exploit. При определенных обстоятельствах двукратное освобождение памяти приводит к выполнению произвольного кода, а не только к сбою в программе. Точно так же отсутствие в нужном месте операции освобождения выделенной памяти делает возможными DoS-атаки. Использование функции _alloca требует особо вниматель ной проверки — если хакеру удастся заставить приложение выделить слишком большой буфер в стеке, это чревато перерасходом стековой памяти и крахом приложения. Я, как правило, советую вообще не использовать функцию _alloca, a в рекурсивной функции тем более.</p><p> Если приложение одновременно работает с наборами символов Unicode и ANSI, будьте особенно аккуратны с функциями преобразования между форматами. Вот прототип функции WideCharToMultiByte-.</p><p> int WideCharToMultiByte( UINT CodePage, // Кодовая страница DWORD dwFlags, // Флаги быстродействия и соответствия LPCWSTR IpWideCharStr, // Строка "широких" символов int cchWideChar, // Число символов в строке LPSTR IpMultlByteStr, // Буфер для новой строки int cbHultiByte, // Размер буфера LPCSTR IpDefaultChar, // Значение по умолчании для не поддающихся // преобразованию символов LPBOOL IpUsedDefaultChar // Устанавливается, если в выходной строке // содержатся символы по умолчанию );</p><p> Четвертый параметр — это число «широких» символов (Unicode) в переданной строке, но размер выходного буфера измеряется в байтах. MultiByteToWideChar ведет себя похожим образом. Хотя это может показаться слишком запутанным, все же помните, что выходная строка представлена в многобайтовом наборе символов, а не в ANSI. Еще один хороший пример набора API-функций, в котором размер ность буфера часто отличается (в байтах или «широких* символах), — это DCOM интерфейс для администрирования IIS в C++. При разборе выясняется, что функ ции, требующие числа в байтах, способны возвращать бинарные данные, а это источник очень хитрых неполадок. Также нельзя забывать, что автор кода (или документации) мог некорректно использовать венгерскую нотацию, так что пр. > веряйте соответствие типа переменной объявленному.</p><p> Нелишне упомянуть о потенциальной проблеме с типом TCHAR. Это может быть как char, так и WCHAR — все зависит от наличия или отсутствия директивы ^define UNICODE в исходном файле. Я видел немало ошибок, возникших из-за путаницы с размерностью буфера — однобайтовый или двухбайтовый. Я предпочитаю все гда явно использовать именно тот тип символов, который мне необходим, 540 Часть IV Особые вопросы Переполнение целочисленных буферов Этот тип переполнения — одни из моих «любимых*. Я был восхищен, сколькими способами представляется информация в компьютере, когда писал программу моделирования аэродинамической поверхности крыла. Манипуляции с больши ми матрицами с использованием арифметики с плавающей точкой стали для меня хорошей «школой жизни». Большинство программистов работают только с целыми типами и сталкиваются лишь в двумя основными классами проблем. Рассмотрим ошибки, связанные со знаковым и беззнаковым представлениями.</p><p> int Example(char* str, int size) char buf[BO];</p><p> if(size < sizeof(buf)) ' //Должно быть безопасно...</p><p> strcpy(buf, str);</p><p> } А теперь быстро отвечайте: в чем здесь проблема? Что, никак? Ну хорошо, под скажу: любой целый тип практически всегда предусматривает знак. Но sizeof воз вращает беззнаковый тип sizej. А если вызывающий передаст отрицательное число в качестве параметра size'. Предположим, что компилятор приведет sizeof(buf) к знаковому целочисленному типу, сравнение пройдет успешно и буфер перепол нится. Решение проблемы в том, чтобы всегда объявлять целочисленные перемен ные беззнаковыми, если только вам не нужны отрицательные числа. Большинство систем считают целый тип знаковым, если только он не объявлен явно как без знаковый. К счастью, компилятор сообщит о несовпадении знаковых и беззнако вых типов, если только программист не отключит предупреждения. Внимательно изучите сравнения длин строк и не игнорируйте предупреждения компилятора о несовпадении знаковых и беззнаковых типов. Если программист приводит типы, не обращая внимания на предупреждения компилятора, смотрите внимательнее — здесь может таиться ошибка, представляющая опасность для защиты!</p><p> Еще один способ нарваться на неприятности — прибавить единицу к MAX_INT.</p><p> Если у вас есть код, прибавляющий заданный размер к завершающему разделите лю, убедитесь, что перед прибавлением выполнена проверка размера, или явно проверяйте на возникновение переполнения следующим образом:</p><p> IfCresult < original) //Ошибка!</p><p> return false;</p><p> Эта ошибка часто возникает при использовании функции GefTickCount для хронометрии приложения. GetTickCount сбрасывается примерно через 40 дней, что следует принимать во внимание.</p><p> ГЛАВА 20 Анализ безопасности кода Переполнение целого типа — непочатый край для совершения самых замыс ловатых ошибок. Посмотрите на следующее определение типа:</p><p> typedef struct _LSAJJNICODE_STRING { USHORT Length;</p><p> USHORT MaximumLength;</p><p> PWSTR Buffer;</p><p> } LSA_UNICODE_STRING;</p><p> Поля Length и MaximumLength хранят количество байт, которые может содер жать буфер, то есть до 32 768 Unicode-символов. Вот возможная реализация ф\ и кции, принимающей указатель WCHAR и инициализирующий одну из таких струк тур:</p><p> void InitLsaUnicodeStringCconst WCHAR* str, LSA_UNICODE_STR« pUnicodeStr) { Iffstr == NULL) I pUnicodeStr->Buffer = NULL;</p><p> pUnicodeStr->Length = 0;</p><p> pUnicodeStr->MaximumLength = 0;</p><p> else unsigned short len = (unsigned short)wcslen(str) * sizeof(WCHAR);</p><p> pUnicodeStr->Buffer = str;</p><p> pUnicodeStr->Length = len;</p><p> pUnicodeStr->MaximumLength = len;</p><p> } Внимательно изучите код;</p><p> посмотрите, что случится, если кто-то передаст строку длиной 32 769 байт. Если рядом есть компьютер, запустите калькулятор (calc.exe) и посчитайте вместе со мной. Сначала разделим на 2. Переключившись в шест надцатеричное представление, увидим, что длина равна 0x10002. А приведя ре зультат к типу unsigned short, обнаружим, что поле Length содержит 2! Чтобы окон чательно осознать последствия, вообразите, что произойдет, когда структура LSAJJNICODE_STRING будет передана в функцию! Проверяется только, что Length меньше MaximumLength приемника, после чего вызывается wcscpyl Будьте осоио внимательны при отбрасывании разрядов (truncating) в целых числах. Вот KLIK выглядит улучшенная версия этого кода:</p><p> unsigned long len = wcslen(str) * sizeof(WCHAR);</p><p> if(len > Oxffff) -;</p><p> pUnicodeStr->Buffer = NULL;</p><p> pUnicodeStr->Length = 0;</p><p> 542 Часть IV Особые вопросы pUnicodeStr->MaximumLength = 0;</p><p> :</p><p> Теперь рассмотрим еще одну возможность напортачить с целыми числами: ум ножение, которое чревато ошибками. Пример:</p><p> int AllocateStructs(void** ppMem, unsigned short StructSize, unsigned short Count) unsigned short bytes_req;</p><p> bytes_req = StructSize * Count;</p><p> *ppMem = malloc(bytes_req);</p><p> if(-ppMem == NULL) return -1;</p><p> else return 0;</p><p> Как и в примере с LSA_UNICODE_STRING, вполне возможно, что умножение вызовет переполнение, которое приведет к тому, что выделенный буфер окажет ся слишком маленьким для этой задачи и последующее копирование данных в него вызовет переполнение. В этом примере объявление bytes_req типа unsigned integer решает проблему. А вот более надежный способ:</p><p> int AllocateStructsfvoid** ppHem, unsigned short StructSize, unsigned short Count) unsigned short bytes_req;</p><p> ifCStructSize == 0 | Count > Oxffff/StructSize) | !</p><p> assert(false);</p><p> return -1;</p><p> bytes_req = StructSize * Count;</p><p> *ppMem = malloc(bytes_req);</p><p> if(«ppMem == NULL) return -1;</p><p> else return 0;</p><p> \ Если в программе есть пользовательские функции для выделения памяти, ве лика вероятность, что они не •учитывают переполнения целочисленных перемен ных. Это переполнение может скрываться внутри сложных проверок того, выде ГЛАВА 20 Анализ безопасности кода ляются ли блоки только определенного размера. Всякий раз, когда видите опера цию умножения целых чисел, пытайтесь разобраться, что произойдет в случае переполнения.</p><p> Еще один интересный вопрос переполнения целочисленных буферов: указа тель — беззнаковое целое, содержащее адрес в памяти. Арифметика указателей подвержена тем же проблемам, что описанные выше любые другие арифметические действия над целыми числами. Выполняя арифметические действия над указате лями, старайтесь предотвращать переполнение. Следует помнить, что это как р;</p><p>яз та область, где взломщик обычно ищет лазейку. Простое переполнение строко вых буферов становится все труднее отыскать в коде, так что хакеры сейчас вплот ную занимаются поиском более хитрых ошибок.</p><p> Родственная проблема: когда буфер слишком мал Допустим, есть такой код:</p><p> void AllocMemory(size_t cbAllocSize) { // Не будем выделять память для завершающего ДО' cbAllocSize--;</p><p> char «szData = malloc(cbAllocSize);</p><p> На первый взгляд вроде бы все нормально, пока не поймешь, что случится если присвоить cbAllocSize == 01 Неприятности грозят в двух случаях: если код не вы полняет проверку:</p><p> SzOATA != NULL или если cbAllocSize оказывается равным -Л В первом случае (целое со зна ком) на сервере класса «high-end» -/ превращается в что-то около 4 000 000 ОСО.</p><p> Мораль такова: будьте осторожны с кодом, где целое может стать меньше нуля, Проверка возвращаемых значений Вообще -то не стоит лишний раз говорить то, что подсказывает обычный здравый смысл, но все же: необходимо проверять все вызовы функций, возвращающих ошибки. Если функция не возвращает ошибку, неплохо проверять, действитель но ли операция завершилась успешно. Хороший пример — проверка буфера пос ле вызова strncpy. чтобы выяснить, действительно ли обрезана строка (см. главу S).</p><p> Исключительно важно проверять значения, возвращаемые критически важными функциями безопасности, такими, как функции олицетворения, например Imperso nateNamedPipeClient. Большинство функций легко проверить на ошибки, но у некоторых три возможных возвращаемых значения, в частности так ведут себя отдельные функции для работы с сонетами.</p><p> Взгляните на этот код;</p><p> whilefbytes = recv(sock, buf, len, 0)) WriteFileChFile, buf, bytes, iwritten, NULL);</p><p> Особые вопросы 544 Часть IV Что здесь не так? Обычно recv возвращает О, если больше не остается байт для чтения с: TCP-подключения. После этого предполагается корректное закрытие подключения. Если же подключение в силу каких-то причин было разорвано, bytes будет присвоено значение -1 и WriteFile попытается записать четыре гигабайта в файл, на который указывает описатель bFile. Приложение инициирует исключе ние (если только программа не выполняется в 64-разрядной операционной сис теме).</p><p> Если у вас до сих пор не возникало особых проблем, то скажу, что есть функ ции, при вызове которых недостаточно проверять лишь успешность завершения.</p><p> Например AdjusflbkenPrivileges. В документации говорится:</p><p> Завершившись успешно, функция возвращает отличное от пуля значение. Чтобы определить, всели из указанных привилегий ус тановлены, вызовите GetLastError, которая, при условии успешного завершения функции, вернет одно из следующих значений:</p><p> Значение Смысл -^_ Функция установила все заданные привилегии ERROR_SVCCESS У маркера нет одной или нескольких из указанных в пара ERRQR_NOT_ALL_ASSIGNED метре Neti'State привилегий. Функция может успешно вы полниться с этой ошибкой даже если не было установлено ни одной привилегии. Параметр PreviousState информиру ет об успешно установленных привилегиях Можно подумать, что, когда надо установить одну привилегию, функция завер шится с ошибкой, если не сможет ее установить. К сожалению, она вернет TRUE, и вам придется вызвать GetLastError чтобы определить, действительно ли приви легия установлена. Это особенно важно при удалении привилегий. Вывод: если вы недостаточно знакомы с поведением используемой функции, внимательно читайте раздел примечаний — это позволит найти очень интересные ошибки.</p><p> Особо тщательная проверка кода с указателями Анализ «эксплуатации» переполнения буфера показывает, что самый популярный метод взлома — перезапись указателя с целью изменения хода выполнения про граммы, Поэтому дважды проверяйте на предмет переполнения буфера весь код, в котором есть указатели. Сюда относятся классы C++ с виртуальными методами, указатели на функции, связанные списки и т.п. Ясно, что проще всего перезапи сать адрес возврата функции, основанной на стеке.</p><p> Никогда не доверяйте данным Надеюсь, я уже вдолбил вам эту мысль в предыдущих главах, однако здесь есть одна интересная особенность, неприятная для тех, кто работает с типами документов и сетевыми протоколами. Предполагая, что клиент (или приложение, породившее документ) «белый и пушистый», потому что создан в вашей группе, вы можете подставить себя под удар. Вот наглядный пример общей проблемы. Представьте, что имеете дело с сетевым протоколом, который пересылает данные в виде струк туры:</p><p> Анализ безопасности кода ГЛАВА struct blob I DWORD Size;</p><p> BYTE* Data;</p><p> >:</p><p> Выглядит очень просто, но таит множество проблем. Взломщик может указать размер вплоть до 4 Гб. Выделяя буфер на основании поля Size, непременно про веряйте его на «порядочность». С другой стороны, если взломщик задаст размер, гораздо меньший, чем реальные данные, клиент начнет считывать данные в по исках разделителя (или просто конца переданных данных) и переполнит буфер.</p><p> Эта проблема более вероятна при получении данных из сети, а не из докумегг а, но и с документами возможны неприятности. Размер (Size) документа иног. i,a больше реальных данных — при передаче по сети это обычно вызывает тайм-аут ы.</p><p> Такие ошибки становились причиной самых различных проблем с безопаснос тью в приложениях пакета Microsoft Office. Корень зла всегда оказывался в том, что предполагалось, что документ создан доверенным клиентом.</p><p> Резюме В этой главе рассмотрены вопросы, которым следует уделять особое внимание при анализе кода на предмет брешей в безопасности. Старайтесь более жестко и фор мализовано анализировать код. наиболее подверженный риску, а если анализи руете большое приложение, примените модели опасностей и диаграммы поток! >в данных для обнаружения фрагментов, требующих особого внимания. Перепол нение целочисленных переменных часто ускользает из поля зрения программи ста, но взломщики рассматривают их как новый перспективный источник лазе ек. Желаю вам, чтобы ваша программа не оставляла им ни малейшего шанса!</p><noindex> <div class="reklama"> <center> <a rel="nofollow" target="_blank" href="http://www.dobrota.biz/stati/chto-takoe-saentologiya.php" title=""> <table> <tr> <td> <img src="http://www.dobrota.biz/stati/images/scientology.jpeg" border="0" alt="" hspace="30" vspace="20" align="right" width=130 > </td> <td> <font size=+3>Узнайте, что такое Саентология... </font><br><br> <center><font color=red size=+1>Ваша жизнь поменяется...</font><br><br> </center> </td> </tr> </table> </a> </center> </div> </noindex> <p> ГЛАВА Безопасная установка приложений У становка ПО — одна из составляющих, безопасности которой по непонятной причине не придают большого значения, но существенная часть «заплаток» ис правляет изъяны именно этого процесса. Довольно неприятно, когда скрупулез но и тщательно написанное приложение, например сетевая служба, в которой вы устранили все возможности переполнения буфера и DoS-атак, превращается про цедурой установки в программу, используемую взломщиками для захвата локаль ных привилегий.</p><p> Корень зла в том, что большинство популярных установочных утилит — по крайней мере па момент написания этой книги — понятия не имеют ни о какой безопасности. Будем надеяться на изменения к лучшему в будущем, но пока для обеспечения безопасности установки приходится прикладывать дополнительные усилия. Даже если в установочном ПО не предусмотрена возможность защиты приложения, для этого разрешается вызывать внешние процессы. Например, можно запустить собственное приложение для настройки конфигурации безопасности или — в Windows 2000 (или выше) или Windows NT 4 — воспользоваться редак тором безопасности Security Configuration Editor, тем самым сэкономив массу времени и сил.</p><p> Я столкнулся с этой проблемой во время работы над инструментом Internet Security Scanner в компании Internet Security Systems. Занимаясь переносом этого сканера с UNIX на Windows NT, я размышлял о том, как быстро это приложение собирает уйму информации о путях проникновения в сетевые системы. Такого рода сведения явно не предназначены для посторонних глаз. Затем я взглянул на раз делы реестра с данными конфигурации безопасности и ужаснулся масштабу ка тастрофических последствий, возможных в результате того, что кто-то изменит ненадлежащим образом конфигурацию, например сделав возможными массиро ГЛАВА 21 Безопасная установка приложений ванные DoS-атаки. Но к концу проекта, при каждом запуске приложения-сканера проверялось, чтобы права доступа ко всем каталогам с файлами приложения и с выходными данными предоставлялись только администраторам;</p><p> к тому же мы разработали приложения для надлежащего конфигурирования доступа к файло вой системе и реестру. Понятно, что инструмент аудита сетевой безопасности — это особенное приложение, требующее исключительно тщательной защиты, но я впоследствии обнаружил в самой операционной системе много параметров безопасности, значения которых, заданные по умолчанию, делали систему уязви мой для атак. Для всех обнаруженных мной уязвимых мест вскоре были выпуше ны «заплатки», и ко времени выхода Windows 2000 параметры безопасности по умолчанию значительно улучшились, Принцип минимальных привилегий Принцип минимальных привилегий гласит, что пользователю предоставляется возможность совершать только необходимые действия, и не более того. Правильно «соорудив* границу между местоположениями исполняемых файлов и пользова тельских данных, вы значительно облегчите защиту приложений, а также обес печите большую совместимость с Windows 2000 (и более поздними версиями). Так что тщательно продумайте, кому же действительно следует предоставить возмож ность перезаписывать исполняемые файлы. Обычно полный доступ необходим администраторам и, если возможна установка личной копии приложения рядо вым пользователем, учетной записи CREATOR OWNER (Создатель-владелец). А кому разрешить запись данных в установочный каталог приложения? Вообще-то ни кому — файлы рядовых пользователей должны храниться в их профилях. Если же вы все-таки решили позволить пользователям запись файлов в общий каталог, необходимо позаботиться о настройке прав доступа.</p><p> Перейдем к конфигурационным параметрам. Я надеюсь, что конфигурацию разных пользователей вы храните в отдельных разделах реестра HKEYjCUR RENTJJSER, а не в HKEY_LQCAL_MACHINE, С конфигурационными данными следу ет поступать так же, как и при настройке доступа в файловой системе. Действи тельно ли приложение настолько конфиденциально, что нельзя позволять пользо вателям без администраторских полномочий изменять значения параметров? Не приведет ли модификация какого-либо параметра конфигурации к повышению привилегий?</p><p> Рассмотрим несколько реальных примеров. Служба Systems Management Server (SMS) Remote Agent выполняется в контексте локальной системы, но по умолча нию к папке, в которую она устанавливается, предоставляется полный доступ всем.</p><p> Подробно об этой проблеме (и о способе ее решения) рассказано на странице bftp://www.microsqft.com/tecbnet/secunly/bulletin/fqOO-012.asp. Мне известно, что эта ошибка встречается и в службах других производителей. Вообще говоря, никогда нельэЙ предоставлять права на изменение файлов приложения абсолютно всем, а если приложение предназначено для работы в администраторском контексте или под учетной записью Local System, то только администраторы должны иметь право модифицировать исполняемый файл.</p><p> С имеющимися в Windows NT 4.0 разрешениями раздела реестра AeDebug свя зана еще одна проблема. В AeDebug указывается приложение, которое должно Особые вопросы 548 Часть IV выполняться в случае аварийного завершения другого приложения. Даже если исполняемый код «упавшего» приложения должным образом защищен средства ми файловой системы, а его конфигурационные параметры — нет, складывается угрожающая ситуация (подробности — на странице http://ivww.microsoft.com/Tecb Net/security/bulletin/fqOO-OOS.asp). «Ну и что?» — спросите вы, Если рухнет одно из приложений, просто запустится отладчик в контексте текущего пользователя. А что, если приложение выполняется под учетной записью Local System и уязвимо для DoS-атак? (Этот пример прекрасно демонстрирует, как даже крах приложе ния ставит систему под удар.) Ведь ничего не стоит подменить адрес отладчика, вызвать крах приложения и получить возможность выполнять любой код в кон тексте локальной системы!</p><p> Существует менее опасная разновидность этой угрозы, связанная с особенно стями параметров протокола SNMP (Simple Network Management Protocol) (под робно — на странице bttp://ttnvw.microsofiom/TecbNet/security/bulletm/fqOO-096.asp).</p><p> SNMP [название этого протокола мой друг расшифровывает как «Security Not My Problem» (безопасность — не моя проблема)] — незащищенный протокол, широ ко используемый для повседневных операций по управлению сетью. Управление доступом в протоколе SNMP основано на общем секрете — так называемой общей сроке (community string). Это не совсем хорошо, так как секрет находится на де сятках устройств и, а это очень плохо, передается практически открытым текстом (схема его кодирования основана на искажении и очень неудобна для програм мирования). Любой, кто обладает сетевым анализатором (sniffer), в состоянии, перехватив нужные пакеты, расшифровать их и узнать секрет. Проблема с разре шениями заключается в том, что по умолчанию к подразделу реестра Parameters.</p><p> относящегося к службе SNMP, предоставляется доступ для чтения всем пользо вателям (точнее, всем локальным пользователям). А, получив доступ к общей строке, разрешающей доступ на запись, рядовой пользователь сможет выполнять SNMP запросы SET и, значит, практически любые операции. Существуют и более «запу щенные» случаи, обусловленные описанной уязвимостью. Некоторые приложения хранят пароли (часто защищенные слабыми криптографическими средствами или просто открытым текстом) в доступных извне разделах реестра или /гаже в фай лах. Важно помнить, что есть информация, которая ни в коем случае не должна предоставляться любому, имеющему доступ в систему. Подумайте, нет ли в вашем приложении подобной информации, и позаботьтесь о надлежащей ее защите.</p><p> Иногда я сталкиваюсь с другой проблемой: информация различного уровня конфиденциальности хранится в одном разделе реестре. В отличие от файловой системы, в реестре нельзя установить различные правила доступа к разным пара метрам одного подраздела. Представим себе ситуацию, когда одному параметру требуется серьезная защита (например, сведения учетной записи службы), а дру гой параметр должен быть легко доступным для изменения из приложения. Воз никает проблема. Чтобы обеспечить безопасность раздела, доступ к нему следует предоставить только администраторам, поэтому приложение придется выполнять в контексте с правами администратора. Но теперь, если злоумышленник взлома ет приложение, он получит доступ ко всей системе. При выполнении приложе ния под учетной записью рядового пользователя атакующему остается только использовать программу для изменения конфиденциального параметра. Итак, ГЛАВА 21 Безопасная установка приложений вывод: в одном разделе реестра следует хранить информацию только одного уровня безопасности. Эта касается и конфигурационных файлов.</p><p> Недавно группа разработчиков попросила у меня совета, как лучше защитить части их приложения. Я спросил, каким образом они защитили свои файлы, и они ответили: «Все файлы записываются в каталог Program Files, ведь его параметры доступа по умолчанию обеспечивают удовлетворительную защиту*. Действитель но, у каталога Program Files неплохой набор разрешений, но я поинтересовался, что произойдет, если пользователь предпочтет для установки другой каталог, на пример корневой каталог только что отформатированного раздела NTFS. На ли цах моих собеседников появилась озабоченность, и не зря — ведь в этом случае приложение окажется доступным всем. Чтобы избежать подобного конфуза, са мостоятельно устанавливайте списки ACL на каталогах.</p><p> Убирайте за собой!</p><p> Когда программа установки оставляет где попало файлы с паролями в открытом или слабо зашифрованном виде, сразу возникает масса проблем. Если при уста новке приходится иметь дело с паролями или другой весьма конфиденциальж >й информацией, проверьте, не остается ли она после завершения процесса в каком нибудь временном файле. Один способ решения этой проблем — использование специальной установочной программы, которая безопасно работает с паролями, а второй — предусмотреть дополнительный этап после завершения установки, во время которого удаляются все ненужные файлы. Во втором случае возможны про блемы, если процесс установки прерывается, например при крахе или прерыва нии работы установочной программы [обычно это делают посредством Task Mar а ger (Диспетчер задач)], и следующие за установкой этапы не выполняются. Оставля [ъ пароли в файлах, размещенных где попало на жестком диске. — прекрасный споо го нарваться на серьезные неприятности!</p><p> Редактор конфигурации безопасности Редактор конфигурации безопасности (Security Configuration Editor) появился в Sendee Pack 4 для Windows NT 4 и присутствует по умолчанию в Windows 2000 и последующих ОС. В его состав входит пара оснасток консоли управления Microsoft (Microsoft Management Console, MM С) и утилита командной строки. Допустим, вы тщательно продумали способ обеспечения безопасности приложения: ваше при ложение устанавливается в единственный каталог и создает только один раздел в реестре внутри HKEY_LOCAL_MACHINE\Software. Откройте окно ММС и добаиыс оснастки Security Templates (Шаблоны безопасности) и Security Configuration and Analysis (Анализ и настройка безопасности) (рис. 21-1).</p><p> Далее следует создать специальные шаблоны (templates) и базы данных безо пасности (security databases). Сперва примените шаблон, иначе инструмент не позволит создать базу данных. Раскройте узел Security Templates, щелкните пра вой кнопкой %<установочная_папка_ОО%\5есип1у\Тетр1а1е и в контекстном MCI ю выберите команду New Template (Создать шаблон). В открывшемся окне опреде лите имя нового шаблона. Так как новый шаблон — пустой, я обозвал его null. На рис. 21-2 показан вид ММС-консоли после создания нового шаблона, Особые вопросы Часть IV ;</p><p>;</p><p> *.</p><p> Рис. 21-1. Окно добавления/удаления оснасток с оснастками Security Templates и Security Configuration And Analysis Default Seturliy sottinos. Rtquirs ^ ConseJe Root Default S«urky Snttings. L-sw R -i j ) Security |.- -за дияияиамвииви Default Sicullly iettmos. L. ei^*S\Rest™:ted G..</p><p> » fcsumes<lean-instalWF5H*V"o.acls. RelixgsA..</p><p> * JBe:\ne™PP ;</p><p>-: Й1 Security Configuration a^d Дгн1у5в ftssumes tiean чп«а1 NT FSntal™g*CLs. includes.</p><p> [nereases ЗвсиичгаЗЯПгчр. Restricts Power Us..</p><p> empanel! RtoSecun!.. Many of the Ftes..</p><p> L^Tcanant Rle^etuntj. Many of the hips..</p><p> Se ftssuinesclEar-rstalMTFSflelregftCLs.</p><p> Out у bos defa* жи*у settniis Рис. 21-2. ММС-консолъ с шаблоном безопасности null А теперь создадим базу данных новой конфигурации безопасности. Щелкни те правой кнопкой Security Configuration and Analysis и в контекстном меню вы берите команду Open Database (Открыть базу данных). Введите имя и путь к со здаваемой базе данных;</p><p> свою я назвал NewAppsdb. В диалоговом окне Import Template (Импортировать шаблон) предлагается выбрать шаблон, который будет сопоставлен базе данных. Выберите только что созданный шаблон null (рис. 21-3).</p><p> Затем создадим шаблон с желаемой конфигурацией приложения. Предваритель но создайте раздел реестра и каталог, которые придется указать далее при настройке параметров. Вернитесь в основное окно ММС-консоли (рис. 21-4), разверните узел шаблона null, щелкните правой кнопкой раздел Registry (Реестр) и в контекстном меню выберите команду Add Key (Добавить раздел), ГЛАВА 21 Безопасная установка приложений Г) > Рис. 21-3. Диалоговое окно import Template, где выбирается шаблон для базы данных D LiS В t _S 0 VA'J.'JTISecurityiTsmplele • ИЗ |Г'Л!М :-;</p><p> ГЗ НелЛес ^ДЯ^РоЬ,(!</p><p> -at] Event Lo^ iiS ^e^tnctedGr^jp^ ^ 5/starri5erv»tsa | FfeE-sten »i inly CunfiguatiHi and Analyse Рис. 21-4. ММС-консолъ с новым шаблоном в развернутом виде Выберите в диалоговом окне Select Registry Key (Выбор раздела реестра) со зданный раздел реестра и установите необходимые разрешения в окне настрой ки свойств безопасности базы данных (то есть списков ACL). Повторите те же операции с папкой File System (Файловая система). Специальные разрешения на отдельные файлы следует настроить здесь. Сохраните шаблон и закройте ММ>'> консоль, чтобы разблокировать базу данных. Открыв шаблон в Notepad (Блокнот), вы увидите следующее:</p><p> [Unicode] Unicode=yes [Registry Values] [Registry Keys] "MACHINE\SOFTWARE\NewApp",0,"D:PAR(A;</p><p>Old;</p><p>KA;</p><p>;</p><p>;</p><p>BA}(A;</p><p>CI;</p><p>CCSWRC;</p><p>;</p><p>;</p><p> WD) " [File Security] "E:\NewApp",0,"D:AR(A;</p><p>OICI;</p><p>FA;</p><p>;</p><p>;</p><p>BA)(A;</p><p>OICI;</p><p>Ox1fOOe9;</p><p>;</p><p> ;</p><p>W D)" [Version] signature="$CHICAGO$" Revision= 19- Часть IV Особые вопросы Отредактируйте строки, указывающие на корень установочного каталога (в нашем примере E:'\NewApp), и измените их на строку %newapp_install%. Затем ском пилируйте и выполните следующий код (см. папку Secureco2\Chapter2 1 \SecInstall), Л Это приложение получает INF-файл шаблона безопасности, заменяет !Enewapp_installX на указанный (или выбранный) пользователем каталог и записывает его в специальный файл с расширением. inf, который затем можно применить к выбранному пользователем каталогу, ttdefine UNICODE ((include <windows.h> tfinclude <stdio.h> /* Пне совсем не нравится отслеживать все ветви программы, проверяя не промахнулся ли где-то с описателями, поэтому я создаю множество классов, похожих на те, что есть в этой программе.</p><p> */ class SmartHandle I public:</p><p> SmartHandleO ( Handle = INVALID_HANDLE_VALUE;</p><p> "SmartHandleO.</p><p> if(lsValidO) I CloseHandle(Handle);</p><p> } I bool isValid(void) I if (Handle 1= INVALID_HANDLE_VALUE && Handle 1= NULL) return true;</p><p> else { return false;</p><p> ' Безопасная установка приложений 5ЬЗ ГЛАВА HANDLE Handle;</p><p> }\ Л Устали от преобразования аргументов в UNICODE?</p><p> Примените функцию «main вместо main, и все аргументы будут сразу передаваться в UNICODE.</p><p> */ int wmain(int argc, WCHAR* argv[]) SmartHandle hlnput;</p><p> SmartHandle hOutput;</p><p> SmartHandle hMap;</p><p> WCHAR* pFile;</p><p> WCHAR* pimp;</p><p> WCHAR* pLast;</p><p> DWORD filesize;</p><p> DWORD dirlen;</p><p> if(argc != 4) { wprintf(L"Cnoco6 применения: Xs [входной файл]", argv[0]>;</p><p> wprintf(L" [выходной файл] [установочный каталогДп");</p><p> return -1;</p><p> I dirlen = wcslen(argv[3]);</p><p> hlnput.Handle = CreateFile(argv[1], GENERIC.READ, О, // Не открываем файл для общего доступа NULL, // He изменяем параметры безопасности OPEN_EXISTING, // Сбой, если файл отсутствует FILE_ATTRIBUTE_NORMAL, // Самый обычный файл NULL);</p><p> // Без шаблона Lf(!hInput.IsValid()) { wprintf(L"He удается открыть Xs\n", argv[1]);</p><p> return -1;</p><p>, DWORD highsize = 0;</p><p> filesize = GetFileSize(hInput.Handle, Ahighsize);</p><p> if(highsize != 0 || filesize == "0) // Размер файла превышает 4 Гб // что это за IMF-файл такой???</p><p> 554 Часть IV Особые вопросы wprintf(L"Pa3Hep fcs неизвестен или слишком велик. \n", argv[1]);</p><p> return -1;</p><p> I Л Аналогично предыдущей функции за исключением того, что файл создается в любом случае */ hOutput. Handle = CreateFile(argv[2], GENERIC_WRITE, О, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);</p><p> if(lhOutput.leValidO) wprlntf(L"He удается открыть lSs\n", argv[2]);</p><p> return -1;</p><p> // Теперь, когда открыты входной и выходной файлы, // создадим проекцию входного файла.</p><p> // У проецируемых память файлов масса преимуществ, // не говоря уже о том, что с ними выполнять многие задачи легче.</p><p> hMap. Handle = CreateFileMapping(hInput. Handle, // Открываем файл.</p><p> NULL, // Никаких специальных параметров защиты.</p><p> PAGE_HEADONLY, // Только для чтения.</p><p> О, // Не задаем максимальный О, // или минимальный размер // используем размер файла.</p><p> NULL);</p><p> // Имя нам не нужно, if(!hMap.IsValid()) I wprintf(L" Невозможно создать проекцию Xs\n", argv[1]};</p><p> return -1;</p><p> :</p><p> // Начинаем с начала файла и создаем полную его проекцию.</p><p> pFile = (WCHAR*)MapViewOfFile(hMap. Handle, FILE_HAP_REAO, 0, О, О);</p><p> if{pFile == NULL) I wprintf(L"He удалось создать проекцию JSs\n", argv[1]);</p><p> return -1;</p><p> ГЛАВА 21 Безопасная установка приложений !</p><p> // Теперь у нас есть указатель на весь файл // поищем нужную строку.</p><p> pTmp = pLast = pFile;</p><p> DWORD subst_len = wcslen(L"Xnewapp_installX");</p><p> whiled) DWORD written, bytes_out;</p><p> рТшр = wcsstr(pLast, L"%newapp_install!T);</p><p> if(pTmp != NULL) \ Ц Новая строка найдена.</p><p> // Сколько байт записывать?</p><p> bytes_out = (pTmp - pLast) * sizeof(WCHAR);</p><p> if(!WriteFile(hOutput.Handle, pLast, bytes_out, &written, NULL) | bytes_out != written ) | i wprintf(L"He удается записать в Ss\n", argv[2 ]);</p><p> return -1;</p><p> // Теперь заменим Slnewapp_installiE на выбранный // пользователем каталог, if(!WriteFile(hOutput.Handle, argv[3], dirlen * sizeof(WCHAR), «.written, NULL) || dirlen * sizeof(WCHAR) != written) !</p><p> wprintf(L"He удается записать в Xs\n", argv[2]);</p><p> UnmapViewOfFile(pFile);</p><p> return -1;</p><p> I pTmp += subst_len;</p><p> pLast = pTmp;</p><p> I else i // Строка не найдена - дописываем остаток файла bytes_out = (BYTE-)pFile + filesize - (BYTE*)pLast;</p><p> if(!WriteFile(hOutput.Handle, pLast, bytes^out, &written, NULL) || bytes_out != written) 556 Часть IV Особые вопросы wprintf(L"3anncb в Ss невозможна\п", argv[2]);</p><p> UnmapViewOfFile(pFile);</p><p> return -1;</p><p> else // Вот и все! Депо сделано!</p><p> UnmapViewOfFile(pFile);</p><p> break;</p><p> I !</p><p> // Остальные описатели магическим образом // закроются автоматически, return 0;</p><p> Здорово, правда? Вы наверняка подумали, что я предложу что-то идиотское, например попрошу пользователя отредактировать inf-файлы. Это было бы бессмыс ленно — пользователи не привыкли выполнять сложные действия, ведь они очень редко заглядывают «в эту дурацкую документацию». Теперь, получив путь к выб ранному пользователем каталогу, просто выполните следующую команду.</p><p> [e:\]secedit /configure /db NewApp.sdb /cfg out.inf /areas REGKEYS FILESTORE /verbose Установка приложения произойдет безопасно — осталось только проверить, совпадают ли установленные разрешения с желаемыми. Также неплохо бы сохра нить файл Out.inf нл случай, если пользователь захочет вернуться к конфигура ции безопасности приложения по умолчанию. Покончив со сложной частью (той, в которой приходится немного шевелить «серым веществом*) и установкой базы данных и INF-файлов, оставшуюся часть работы можно поручить сценариям ус тановки. По моему опыту, на написание подобных операций с нуля и одновре менного обеспечения поддержки Windows NT 3-51 и 4 требуется масса времени, поэтому с уверенностью могу сказать, что сэкономленное благодаря моим реко мендациям время наверняка с лихвой покроет стоимость этой книги!</p><p> Низкоуровневые API-функции безопасности У меня есть огромное преимущество: я могу точно оговаривать версию ОС, для которой предназначаются мои приложения. У большинства других приложений такой возможности нет, и разработчикам приходится создавать установочные утилиты для нескольких версий семейства ОС Windows NT. Доступные системные API отличаются в разных версиях. До появления Windows NT 4 были доступны только низкоуровневые API-функции. При работе с ними требуется крайняя ос торожность, однако если необходимо прямое обращение к описателю безопас ности, я предпочитаю программировать как можно ближе к самой ОС. Например, функция AddAccessAlowedAce неправильно устанавливает биты наследования в за головке АСЕ-записи. Если же выставить все поля АСЕ вручную, а затем вызвать ГЛАВА 21 Безопасная установка приложений AdclAce, результат полностью совпадет с ожидаемым. (Есть еще функция AddAccess AlowedAceEx, которая корректно работает с заголовками АСЕ, но она доступна только в Windows 2000 и последующих ОС.) Применение низкоуровневых API-функций безопасности демонстрируются в многочисленных статьях и примерах, в числе которых и статья вашего покорно го слуги на странице httf)://www.windowsitsecurity.com/Articles/Index.cfm?Article /.О=9б5>б. Если приходится вызывать низкоуровневые API-функции, советую про верять код особенно тщательно. Практически обязательной следует считать сле дующую операцию: после настройки DACL-таблицы средствами пользовательского интерфейса создайте подробный дамп описателя безопасности или сохраните его в двоичном формате со внутренними связями. Затем установите ту же DACL-таб лицу своей программой и сравните результаты, Если они совпадают не полнос тью, выясните почему. Ничего не стоит создать для объекта DACL-таблицу с мас сой ошибок. Чаще всего ошибаются в порядке следования АСЕ-записей и непра вильно трактуют значения флагов заголовка АСЕ, Используйте Windows Installer Объяснять, как работать с установщиком Windows, я не стану — этому посвящена масса других материалов, например документация к Microsoft Platform SDK В Platform SDK описывается ряд проблем с безопасностью, с которыми вы можете столкнуться, а так как SDK обновляется гораздо чаще этой книги, я советую вни мательно прочитать раздел «Guidelines for Authoring Secure Installations» (Руковод ство по созданию безопасных процедур установки). А теперь я познакомлю вас с некоторыми проблемами, с которыми вы наверняка столкнетесь.</p><p> • Как и в других случаях установки ПО, следует особое внимание уделить ус а повке приложений под учетной записью с правами администратора в катало ги с правом доступа на изменение непривилегированными пользователями. В отличие от других установщиков Windows Installer предоставляет таблицу LockPermissions. которая позволяет устанавливать правила доступа к файлам, каталогам и разделам реестра, • У установочного пакета есть ряд свойств, которые можно разделить на част ные (private), открытые (public) и ограниченно открытые (restricted public).</p><p> Если пользователю разрешено изменять свойство, его следует классифициро вать как открытое, но если пакет выполняется с повышенными привилегиями, некоторые свойства должны быть ограниченно открытыми. Никогда не испо. гь зуйте свойства для хранения паролей или другой секретной информации. Ус тановщик Windows может занести таблицу со свойствами в журнал или реестр.</p><p> • При установке службы средствами Windows Installer постарайтесь не конкре тизировать учетную запись, Иначе возникнет проблема: пары «имя пользова теля + пароль» будут храниться в установочном пакете, и конфиденциальная информация может оказаться в файле журнала или реестре. Вдобавок пакет придется обновлять при каждом изменении пароля. Ситуация ухудшается, если служба устанавливается на многие машины под одной учетной записью, что приведет к взаимозависимости индивидуальной защиты этих машин.</p><p> Особые вопросы 558 Часть IV • Установочные пакеты следует заверять цифровыми подписями, чтобы предот вратить их модификацию и подделку;</p><p> это безусловное требование к програм мам, устанавливаемым с повышенными привилегиями. При обновлении уста новочного пакета администратор должен в обязательном порядке обновить цифровую подпись, • Пакет следует разрабатывать так. чтобы ошибка при получении нужных ресурсов не вызывала крах процесса установки и последующие проблемы с безопасно стью. Например, если выполняющемуся с повышенными привилегиями уста новщику не удастся определить местоположение ресурса, взломщик может воспользоваться диалоговым окном Open для манипуляций с файловой систе мой. Для предотвращения такой проблемы следует до начала установки про верять наличие всех необходимых ресурсов и предусмотреть механизмы пе рехода на другой ресурс, когда в процессе установки выбранный становится недоступным. Подробнее о таких механизмах — в документации к Platform SDK.</p><p> • Для корректировки приложения для заданного круга пользователей предназ начены файлы модификации (transforms). В общем случае лучше применять защищенные варианты этих файлов. Они могут храниться как локально (в области, недоступной для обычных пользователей), так и в самом установоч ном пакете.</p><p> • Благодаря поддержке специальных операций (custom actions) можно создавать процедуры установки, вызывающие внешние исполняемые файлы. Хоть и редко, но иногда для установки приложения требуется больше возможностей, чем есть у Windows Installer, поэтому возможность расширить круг поддерживаемых операций всегда кстати. Если установщик выполняется с повышенными при вилегиями, специальные операции выполняются в контексте пользователя, устанавливающего приложение, если только не установлен бит msidbCustom ActionTypeNoImpersonate — в этом случае установку разрешено производить только администратору.</p><p> Для создания пакета установки средствами Windows Installer обычно требуют ся дополнительные усилия, они оправдываются, когда требуется предоставить возможность устанавливать приложения не только администратору, но и обыч ным пользователям. К тому же Windows Installer — один из немногих установщи ков, поддерживающих настройку параметров безопасности.</p><p> Резюме В этой главе описаны некоторые возможные ошибки, которые программисты часто допускают при разработке процедуры установки приложения. Хотя создание та ких процедур не слишком-то захватывающее занятие, да и не приносит оно ни каких лавров, но совершенные на этой стадии ошибки подчас чреваты серьезны ми нарушениями безопасности системы. Запланируйте настройку разрешений доступа к секретным данным и никогда не надейтесь на то, что унаследованных разрешений окажется достаточно.</p><p> ГЛАВА Обеспечение конфиденциальности д о эры широкого распространения персональных компьютеров и тотального увлечения Интернетом нарушение конфиденциальности* (privacy) рассматрива лось как прерогатива компетентных органов. Все боялись прослушки телефона, перлюстрации почты и слежки. В наши дни любая транзакция представляет со бой угрозу нарушения нашей конфиденциальности, будь то использование дис контной карты в бакалейном магазине, покупка дома или программ в Интерне те — мы рискуем, что информация о нас станет доступна посторонним лицам, которые огласят се или используют нам во вред. Каждый случай нарушения кон фиденциальности подрывает доверие потребителей и, следовательно, отрицательно влияет на коммерческий результат. Анализ текущего состояния финансовых рынков показывает, что дело скорее в недостатке доверия к тому, что делают компании, чем в реальных причинах, обусловленных особенностями бизнеса.</p><p> Внимание! Основную угрозу для конфиденциальности представляет раскры тие информации. Анализируя опасности, следует рассматривать эти уг розы как потенциальные нарушения конфиденциальности.</p><p> Вы себя чувствуете одинаково комфортно, когда покупаете Porsche в комис сионном магазине и у официального дилера? Скорее всего нет, даже если у нас нет веских оснований подозревать неладное. Все дело в доверии. Соблюдение конфиденциальности клиента — ключевой момент в построении доверительных отношений. Люди будут чувствовать себя комфортно, покупая ваши продукты или услуги или инвестируя в вашу компанию, только при условии, что полностью Иногда ее называют приватность. — Прим. псрев.</p><p> Особые вопросы 560 Часть IV доверяют вам. Разрабатывая стратегию соблюдения конфиденциальности для компании, необходимо продемонстрировать, что действительно заботитесь о клиентах. В противном случае будьте готовы отвечать за нарушение конфиден циальности, к потере клиентов и трате массы денег на судебные тяжбы.</p><p> Досаждающие и злонамеренные нарушения конфиденциальности Многие компании нарушают вашу конфиденциальность, пытаясь заполучить но вого клиента. Это обычно лишь раздражает, но не ведет к потере денег и не при носит вреда в долгосрочной перспективе. Достаточно вспомнить о спаме, кото рый вы регулярно получаете. Эти контакты можно разделить на две категории:</p><p> незатребованные обращения от частных лиц и организаций, с которыми вы как то связаны и с которыми никаких отношений пет. В первом случае компании пы таются «впарить» вам что-то новое. Я более чем уверен, что вам доводилось полу чать предложения застраховаться от компании, где вы получили кредитную кар ту, и что вам часто звонят из телефонных фирм и предлагают воспользоваться новой услугой. В любом случае это раздражает клиента: он подумывает о разрыве всяких отношений. Не распугивайте своих клиентов, такими грубыми методами.</p><p> Под злонамеренным нарушением конфиденциальности подразумевает полу чение доступа к персональным данным с целью извлечения выгоды из неэтично го или противозаконного их использования. Многие компании наживаются на продаже контактной информации. У тысяч людей собирают номера кредитных карт, чтобы затем перепродать эту информацию через Web или оставить для соб ственного пользования. Хочется надеяться, что ваша компания не идет на прямое нарушение конфиденциальности. Однако, сами того не зная или не желая, вы мо жете способствовать этому — достаточно вовремя не предпринять нужные шаги для защиты важной информации о клиентах.</p><p> Примечание Однажды я сэкономил кучу денег, купив себе картриджи для цвет ных принтеров на распродаже в Интернете. Через неделю мне сообщи ли, что кто-то воспользовался номером моей кредитной карточки в Корее.</p><p> Стоит ли говорить, что я никогда там не был.</p><p> Законо дател ьство о соблюдении конфиденциальности Законодательство о соблюдении конфиденциальности в США развивается довольно медленно. И как назло, персональная конфиденциальность вступает в противо речие с национальной безопасностью. Различными правительственными агент ствами написано немало отчетов о проблемах конфиденциальности, начиная с «Records, Computers and the Rights of Citizens» (Документы, компьютеры и права граждан), опубликованного Министерством здравоохранения, просвещения и социального обеспечения в июле 19?3]" (http://aspebbsgw/datacncl/1973privacy/ tocprefacemembersJytm). К сожалению, большинство отчетов, созданных после этого документа, почти не годятся для судебной практики. В 1998 г. Федеральная торго ГЛАВА 22 Обеспечение конфиденциальности вая комиссия выпустила документ «Fair Information Practices» (Справедливое ис пользование информации) (bttp://www/tcgov/report$/privacy3/fairinfb.btm). Это была попытка взять лучшее из различных документов о конфиденциальности и объе динить их в одном документе, который применялся бы в судебных тяжбах, каса ющихся неправомерного использования персональной идентификационной ин формации.</p><noindex> <div class="reklama"> <center> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- dissers - kvadr (text2) --> <ins class="adsbygoogle" style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-9894471784993021" data-ad-slot="6763398730"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </center> </div> </noindex><p> Персональная идентификационная информация Персональная идентификационная информация (personally identifiable informal!) m.</p><p> PIIJ — любые сведения, позволяющие идентифицировать или определять мест о пахождение кого-либо. Наиболее наглядный пример РП — имя и адрес. К менее очевидным относятся номер почтового ящика и номерной знак автомобиля. Хотя они и никого не идентифицируют напрямую, но позволяют узнать владельца, В дополнение к этому идентификатор учетной записи и адрес TCP/IP могут рассмат риваться как РП, если напрямую указывают на какие-то персональные данные.</p><p> Следует уделять особое внимание защите РП, хранимой в компании или прило жении, Директивы ЕС о защите данных В октябре 1998 г. Европейский союз опубликовал Директивы о защите данных (bttp:// wivw.cdt.org/privacy/eudirective/EU_Directive_btml), которые определяют, как следует обходиться с РП. Эти директивы запрещают странам Европейского союза предо ставлять РП странам, не входящим в этот союз и не обеспечивающим достаточ ный уровень защиты информации. Это может иметь самые печальные последстьия для американских компаний, ведущих бизнес с ЕС. В отсутствие законодательной базы Министерство торговли США в июле 2000 г. опубликовало Закон о безопас ной зоне, который был признан Европейской комиссией как обеспечивающий соответствующие гарантии. Компаниям в США, согласным соблюдать эти прин ципы, было разрешено вести дела с Европой.</p><p> Закон о безопасной зоне Закон о безопасной зоне (Safe Harbor Principles, http://www.export.gov/safebarbor/) состоит из семи принципов, определяющих правила обращения компаний с пер сональной информацией. Компании, разрабатывающие приложения, должны четко представлять, как эти принципы влияют на способ хранения данных или прило жения, хранящие данные.</p><p> Уведомление Клиент, данные о котором собираются, должен получать полную информацию о том. как они будут использоваться. Каждый Web-сайт должен содержать особое заявление о конфиденциальности (privacy statement), причем на каждой страни це необходимо поместить ссылку на него. В некоторых случаях на страницах для сбора данных следует предусмотреть специальную вставку, где указать, как будут использоваться собираемые данные. В клиентских приложениях надо предусМ'.уг реть меню, позволяющее просматривать политику конфиденциальности, в кото рой описывается, что происходит с данными, сохраняемыми приложением, а также Особые вопросы 562 Часть IV какие данные, отправляются на Web-сайт и обстоятельства, при которых они могут быть переданы третьим лицам.</p><p> Документ с описанием политики конфиденциальности необходимо предъяв лять пользователю в процессе установки или во время первого запуска приложе ния. Разрабатывая приложение, с помощью которого пользователи вашего про дукта будут собирать информацию о клиентах, позаботьтесь о возможности предъ явления клиентам политики конфиденциальности.</p><p> Выбор Пользователю, вводящему данные в ваше приложение, обязательно следует пре доставить возможность определить уровень конфиденциальности до того, как его данные попадут в приложение. Например : он должен иметь возможность сооб щить предпочтительный способ общения — по телефону или электронной почте, а также разрешает ли он, чтобы его персональная информация стала доступна третьим лицам. Кроме того, в приложении следует предусмотреть возможность для клиентов установить параметры конфиденциальности по собственному усмот рению. Например, если вы создаете CRM-приложение (Customer Relationship Mana gement — управление отношениями с клиентами), позаботьтесь для каждой кон тактной записи о возможности сохранения параметров (например, каким обра зом контактировать с клиентом). Подробнее о том, как это сделать рассказывает ся в разделе «Построение инфраструктуры конфиденциальности».</p><p> Дальнейшее распространение Под дальнейшим распространением подразумевается передача персональной информации третьим лицам. Этого должно происходить только с согласия вла дельца информации. Исключение составляют случаи, когда эта третья сторона является вашим агентом и полностью соблюдает политику конфиденциальности, В приложении необходимо предусмотреть механизм разрешений, регулирующий передачу персональной информации третьим лицам.</p><p> Доступ Клиентам следует оставить доступ к собственным данным, в основном для про верки корректности и изменения их по мере необходимости. Клиентам также необходимо иметь право удалить любые данные, которые вы о них храните, если они не нужны для бизнес-задач. Доступ к данным должен быть простым и недо рогим, однако не обязательно прямым и немедленным, тем не менее любые вне сенные клиентом изменения должны попадать во все хранилища данных, в том числе копии данных, которые хранятся у партнеров.</p><p> Безопасность Обеспечивая защиту'данных клиента от неправомерного доступа, следует прояв лять исключительную осторожность. В приложении обязательно предусмотрите функции безопасности, обеспечивающие защиту критически важных данных. Для предотвращения злоупотреблений приложение также должно поддерживать аудит доступа к данным уполномоченных лиц.</p><p> ГЛАВА 22 Обеспечение конфиденциальности Целостность данных Целостность данных пользователя необходимо обеспечивать все время их хра нения. Собирать следует лишь необходимую для дела информацию, а перед ее использованием убедиться в ее полноте и актуальности. Необходимо гарантиро вать защиту персональной информации от несанкционированного изменения, а любые изменения должны вноситься только самим пользователем после должной процедуры аутентификации. Допустимо хранить вспомогательные данные, допол няющие основную информацию о пользователе.</p><p> Возможность предъявления претензий Пользователю следует предоставить простой и очевидный способ связи для предъ явления любых претензий по поводу конфиденциальности. Для этого годится адрес электронной почты или легко доступная Web-форма на вашем сайте. В против ном случае клиенту придется искать другие способы, что грозит потерей прибыли, Хороший способ поощрения доверия в компании — участие в одной из онлай новых программ доверия, поддерживаемых независимыми организациями. При соединившись к такой программе, вы предоставите пользователям возможность обратиться за помощью в случае возникновения проблем с конфиденциальнос тью. На рис. 22-1 показаны логотипы некоторых организаций, поддерживающих программы сертификации: BBBOnline {http://www.bbbonline.com}, ESRB (bttp-// www.esrb.org/wpjom.asp) и TRUSTe (http://www.truste.org/programs/ pub _bow_to_ joinbtmt).</p><p> Рис. 22-1. Логотипы онлайновых программ доверия Прочие законы о конфиденциальности Управление хранящейся у вас информацией о клиентах определяется требованиями законодательства о конфиденциальности для того или иного типа информации, В табл. 22-1 перечислены некоторые федеральные законы США о конфиденциаль ности.</p><p> Таблица 22-1. Федеральные законы США о конфиденциальности Закон Комментарий URL-адрес bttp://wwiv4.law.cor Закон о компьютерном Определяет порядок доступа мошенничестве и зло- к компьютерам других людей nell.edu/uscode/! 8/ 1030 html употреблениях (Computer и запрещает модификацию Fraud and Abuse Act, CFAA) данных, хранящихся на ком пьютерах, в том числе загрузку данных с чужого компьютера без разрешения его владельца см. след. стр.</p><p> Часть IV Особые вопросы Таблица 22-1. (окончание) Закон Комментарий URL-адре^ Акт Грэмма-Лича Блили Определяет порядок обращения bttp://wwwsenate.gQV/ с финансовой информацией. ~banking,/conf/ (Gramm-Leach Bliley Асе, Если вы храните информацию GLBA) такого рода, то обязаны знать и соблюдать этот закон Акт об ответственности Определяет порядок обращения http://cms.l3bs.gov/bipaa/ за распространение меди- с медицинской информацией.</p><p> цинской информации Если вы храните информацию (Health Information такого рода, то обязаны знать Portability Accountability и соблюдать этот закон Act, HIPAA) http://unvwflc.goi :/ора/ Акт о защите детской Определяет порядок сбора конфиденциальности и обращения с информацией 1999/9910/cbildftnalbtm (Children's Online Privacy о детях младше I 3 лет Protection Act, COPPA) Конфиденциальность и безопасность Хотя безопасность и является компонентом конфиденциальности, между ними существует одно отличие. Цель безопасности — ограничить доступ к ценной ин формации лицам, для которых она не предназначена. А конфиденциальность требует от лиц, имеющих доступ к данным, выполнять требования пользователей, касающиеся управления этими данными. Пример соблюдения конфиденциально сти — следование принципам Закона о безопасной зоне. Один из случаев конф ликта безопасности и конфиденциальности — запись в журнал информации о транзакции или пользователе с целью обеспечения безопасности. Внимательно посмотрите, не содержит ли журнал информации, попадающей под политику конфиденциальности. Если в журнале содержится РП, следует либо удалить ее, либо обеспечить надлежащий уровень конфиденциальности журнала.</p><p> Построение инфраструктуры конфиденциальности Для успеха программы конфиденциальности в компании следует собрать коман ду, которая будут ею заниматься. Уже тот факт, что вы занимаетесь этим и пред принимаете усилия в этой области, обеспечит вам дополнительное доверие со сто роны клиентов. Эта команда принесет пользу компании, взяв на себя ряд задач:</p><p> • построение стратегии обеспечения конфиденциальности в компании;</p><p> • создание программы обучения правилам обеспечения конфиденциальности;</p><p> • поддержку последовательной позиции компании в глазах общественности;</p><p> • эффективное реагирование на претензии к компании, касающиеся конфиден циальности;</p><p> • обеспечение соблюдения конфиденциальности при:</p><p> И создании Web-сайтов;</p><p> ГЛАВА 22 Обеспечение конфиденциальности П разработке приложений;</p><p> П управлении персональными данными.</p><p> В крупной компании иногда требуются дополнительные штатные единицы — директор по конфиденциальности (Chief Privacy Officer, CPO) и агенты по кон фиденциальности (privacy advocate) — хотя бы по одному в каждой группе. Ком пании следует участвовать в конференциях по проблемам конфиденциальности и состоять как минимум в одной соответствующей организации. Совет директо ров по конфиденциальности (Council of Chief Privacy Officers, http://wwuKconforenc.e board.org/search/ dcouncil.cfm?councilsid= 173) — одна из таких организаций.</p><p> На рис. 22-2 приведен пример системы обеспечения конфиденциальности в компании. СРО отчитывается перед руководством и управляет командой, ответ ственной за разработку и претворение в жизнь корпоративной стратегии обес печения конфиденциальности. Каждая значимая группа в компании имеет про пагандиста идей конфиденциальности, который тесно сотрудничает с СРО и следит за тем, чтобы его указания четко исполнялись всеми группами в компании.</p><p> Иерархия системы обеспечения конфиденциальности Руководство компании Отдел маркетинга 1.</p><p> Группа разработки Директор по / \\ конфиденциальности Агент по Arm fa конфиденциальности конфиденциальности Группа корпоративной конфиденциальности Рис. 22-2. Схема системы обеспечения конфиденциальности в компании Роль директора по конфиденциальности СРО — это сотрудник, полностью отвечающий за корпоративное видение конфи денциальности и стратегию ее исполнения. Ему необходимо предоставить под держку руководства и полномочия для исполнения корпоративной политики кон фиденциальности во всех группах. Он должен знать последние законы по кон фиденциальности, разбираться, как они влияют на работу компании, и отслежи вать связанные с конфиденциальностью тенденции в отрасли. Нет такой компа нии, руководство которой не заинтересовано в конкурентоспособности, особен но когда дело касается гарантии конфиденциальности. Обязанность СРО — рабо тать с каждой командой разработчиков, знакомить их с ответственностью за бе зопасность данных и следить, чтобы перед выпуском продукта выполнялись все необходимые проверки.</p><p> Часть IV Особые вопросы Роль агента по конфиденциальности Пропагандист идей безопасности играет важнейшую роль в продвижении прин ципов конфиденциальности, разработанных СРО. Он должен формализовать эти концепции в виде плана действий, предназначенного для команды, в которой он работает. В общем случае пропагандист идей безопасности отвечает за решение следующих задач:</p><p> • обучение команды принципам конфиденциальности;</p><p> • помощь в создании заявлений о конфиденциальности;</p><p> • помощь в проектировании функций обеспечения конфиденциальности;</p><p> • обеспечение того, чтобы конфиденциальность стала частью каждой специфи кации проекта:</p><p> • руководство проверкой конфиденциальности каждого компонента по завер шении разработки;</p><p> • помощь в разрешении проблем с конфиденциальностью, относящихся к ком петенции команды.</p><p> Проектирование приложений, обеспечивающих конфиденциальность Создаете вы Web-сервисы или клиентские приложения, конфиденциальность дол жна стоять во главе угла. Это укрепляет доверие клиентов к продуктам компании и выделяет ее среди конкурентов. Проектируя приложение, проанализируйте его со всех точек зрения. Создавая приложения для сбора данных от пользователей, соблюдайте Закон о безопасной зоне. Не забыли ли вы, проектируя приложение, позволяющее другим собирать данные, предусмотреть функцию, предоставляю щую пользователям возможность сохранять свою конфигурацию конфиденциаль ности. Сейчас я расскажу, как разрабатывать ПО с учетом конфиденциальности, и приведу примеры функций, повышающих ценность приложения, Конфиденциальность в процессе разработки Как и в случае с безопасностью, экономия времени и денег достигается за счет соблюдения принципов конфиденциальности на протяжении всего процесса разработки. Агент по конфиденциальности должен понимать процесс разработ ки ПО, в котором участвует его команда, и разработать план интеграции конфи денциальности в процесс (рис. 22-3).</p><p> На этапе проектирования необходимо тщательно проанализировать раздел шаблона, касающийся конфиденциальности, чтобы удостовериться, что охваче ны все важные моменты конфиденциальности. На этапе разработки создается конфиденциальное информационное наполнение Web-сайтов, такое, как политика конфиденциальности и информационное наполнение РЗР (Platform for Privacy Preferences) (о ней мы поговорим далее в этой главе). Кроме того, следует задоку ментировать содержимое cookie-файлов, журналов и любых других данных, по падающих из приложения в Интернет, а также создать документ, описывающий, как используются эти данные. На этапе тестирования проверяется качество реа лизации конфиденциальности и информационного наполнения. Тести ров щи кам ГЛАВА 22 Обеспечение конфиденциальности необходимо тесно сотрудничать с агентом по конфиденциальности, который редактирует все создаваемые документы, тщательно изучая систему конфиденци альности. При выпуске промежуточных версий (альфа-, бета-версии или канди дата на выпуск) следует поддерживать обратную связь с клиентами, аналитиками или СМИ. Собранная информация нужна для пересмотра проекта и внесения со ответствующих изменений в продукт.</p><p> Политика Для документирования Создано и задокументировано Проверочный шаблон конфиден возможных проблем конфиденциальное позволяет удостовериться циальности а создании конфиденциального с конфиденциальностью информационное наполнение, информационного наполнения применяется шаблон например SQM и cookie-файлы и успешном решении проблем Спецификации „ Обратная связь А \ Шаблон спецификации Этап\ Этап Этап Промежуточная Готовый конфиденциальности Этап проек разработки\тестирования проверки версия продукт тирования Политика Информационное конф чденциальности наполнение РЗР Рис, 22-3. Конфиденциальность на каждом этапе процесса создания ПО Шаблон спецификаций конфиденциальности Он должен быть частью общего шаблона проекта функций системы. В нем опи сываются все задачи по конфиденциальности конкретных функций, а также пла ны по выполнению этих задач. Чем тщательнее вы опишете задачи, тем меньше проблем «всплывет» в конце цикла разработки, на этапе проверки. Этот раздел функциональной спецификации следует тщательно проверять перед подтверж дением качества реализации функций. Агент по конфиденциальности должен работать с командой проектировщиков над созданием шаблона спецификации, удовлетворяющего требованиям к разработке.</p><p> Шаблон спецификации конфиденциальности 1. Конфиденциальность В этом разделе описываются случаи нарушения конфиденциальности, воз никающие при работе определенной функции, например раскрытие кон фиденциальной информации пользователя или его привычек при навига ции. Также обязательно задокументировать все данные, поступающие с ком пьютера пользователя. Функции конфиденциальности документируются, как см. след. стр.</p><p> Особые вопросы 568 Часть IV любые другие, и здесь не описываются. Если функция сохраняет конфиден циальную информацию или делится ей с кем-нибудь, то следует ответить на ряд вопросов:</p><p> • как и кто использует эти данные;</p><p> • как долго они хранятся;</p><p> • какую выгоду извлекает из этих операций пользователь;</p><p> • может ли пользователь просматривать и модифицировать данные;</p><p> • запрашивается ли у пользователя явное разрешение перед сохранени ем данных;</p><p> • какие из параметров, задаваемых конечным пользователем, применяются для определения порядка хранения и использования информации;</p><p> • шифруются ли данные;</p><p> • каким третьим лицам становятся известными эти данные?</p><p> 1.1. Клиентский компонент Если рассматриваемая функция является частью клиентского компонента, ответьте на следующий вопрос отправляет ли она данные в Web? Детально опишите содержимое посылаемых данных, время, способ и причину отправ ки. Предоставлена ли пользователю возможность решать, отправлять ли данные? Если да, то какой вариант выбран по умолчанию? Если отправка по умолчанию не запрещена, то обоснуйте, почему это безопасно.</p><p> 1.2 Компонент Web-сервиса Если функция является частью Web-сервиса, следует ответить на такие во просы: есть ли у Web-cepsHca заявление о конфиденциальности? Где оно хранится? Зарегистрировано ли оно корпоративной группой по конфиден циальности? Опишите содержимое и назначение всех cookie-файлов, ко торые предполагается создавать. Опишите содержимое всех журналов, ко торые предполагается вести. Перечислите все уникальные идентификато ры. Реализована ли в Web-сервисе технология РЗР?</p><p> Шаблон проверки конфиденциальности Он применятся для проверки всех параметров конфиденциальности компонен та, который может состоять из нескольких функций. На этом этапе вы должны убедиться, что предотвращены все возможные риски нарушения конфиденциаль ности. Обязательно учтите все конфиденциальное информационное наполнение и параметры. Эту часть проверки должен контролировать агент по конфиденци альности. Все действия, необходимость которых определена в процессе провер ки, следует выполнить до выпуска продукта. Пример полного шаблона есть в пап ке Secureco2\Chapter22.</p><p> Заявление о политике конфиденциальности Оно применяется к Web-сайтам и приложениям. Предусмотрите его для каждого приложения или сервиса, которые планируется развернуть. Корпоративная труп Обеспечение конфиденциальности ГЛАВА па по конфиденциальности, в которую должны входить юридический отдел и отдел связей с общественностью, обязана проверить эту политику на этапе проверки продукта. Политику следует проверять вновь для каждого удачной версии, вклю чая пакеты исправлений. Политика конфиденциальности должна соответствовать Закону о безопасной зоне.</p><p> Это очень важный документ, и на корпоративную группу по конфиденциаль ности возлагается обязанность обеспечивать постоянную его актуальность. На Web сайте организации TRUSTe (http://www.truste.org/bus/pub_re$ourceguide.btmt) опи сано, как создавать заявление о конфиденциальности и приведены примеры. За явление о конфиденциальности компании Microsoft вы найдете на странице bttp:/ /www.microsofl.com/info/privacy.htm, Информационное наполнение РЗР Platform for Privacy Preferences (РЗР) (http://www.w3.org/P3P) — это стандарт, оп ределенный консорциумом W3C (World Wide Web Consortium) и предназначен ный для определения политики конфиденциальности Web-сайтов в виде, понят ном для пользователей и приложений. Почему это должно вас интересовать? Если у вас установлен Internet Explorer 6, вы наверняка видели маленькое изображение глаза со знаком «въезд запрещен* ь строке состояния (рис. 22-4). Это наглядное доказательство работы РЗР Рис. 22-4. Значок конфиденциальности в Internet Explorer Появление этого значка говорит о том, что просматриваемый Web-сайт не удовлетворяет требованиям вашей конфигурации конфиденциальности. Либо политика конфиденциальности конфликтует с одним из параметров безопасно сти браузера, либо такая политика на сайте вовсе отсутствует. Этим сайтам зап рещается размещать cookie-файлы на компьютере. Другие браузеры тоже поддер живают РЗР и предупреждают о несоответствии политик Web-сайтов. На своих Web сайтах реализуйте РЗР так, чтобы это предупреждение не отображалась при среднем уровне (Medium) конфиденциальности. Определение РЗР неразрывно связано с созданием политики конфиденциальности и довольно просто в реализации (< м.</p><p> раздел о реализации РЗР).</p><p> Функции конфиденциальности При проектировании приложений следует неустанно следить за соблюдением конфиденциальности клиентов. Одна из составляющих подобного подхода — простота настройки параметров конфиденциальности самими клиентами. Есть, и другой аспект — удачный выбор способа защиты этих параметров. Помните, что большинство нарушений приватности пользователей лежит на совести тех, кто обладает законным доступом к данным. В этом разделе рассказывается о различных способах записи и защиты конфигурации конфиденциальности пользователей.</p><p> Реализация РЗР Надеюсь, вы уже наслышаны о важности реализации РЗР на Web-сайте. Сначала немного о том, как работает РЗР, а затем о том, легко ли реализовать эту техно/'О Особые вопросы Часть IV гию. В браузере Internet Explorer 6 откройте любой Web-сайт и выберите коман ду Privacy Report (Отчет о конфиденциальности) в меню View (Вид). На рис. 22- показано диалоговое окно, отображаемое для Web-сайтов, на которых не реали зована политика конфиденциальности.</p><p> I this site's privacy I Couldriot find a privacypotcy (оЕНй i policy, contact tfie Web site diiectlji How shadd cookies horn "ечрЬгяйопгв com" be hand © Cameare cookies' Pwaei1 Policy to my settigs О AlwajJ* aitewthis site to LBS cookies.</p><p> О l^ever alow this $йе to use cooWes.</p><p> Рис. 22-5. Диалоговое окно отчета о конфиденциальности при отсутствии поддержки РЗР На Web-сайтах, реализующих РЗР, вы увидите диалоговое окно, показанное на рис. 22-6. Согласитесь, что к такому сайту у пользователей больше доверия. Зна чок TRUSTe может также стать дополнительным подтверждением добрых намере ний и вызовет положительные эмоции v посетителей.</p><p> Privacy Summary for:</p><p> Microsoft Corpc ration To read this Wab site's complete privacy policy, click h e t з ^ Privacy Certificate:</p><p> How should cookies from "miciusoft.com" be tiancfed?</p><p> ф Correaie cookies' Rivac!' Pclcji to rrji settings.</p><p> C* ^l™^15 alkwi ftc silo lo use cookies, О fS evsr E^loiw this ив to use cookies Рис. 22-6. Отчет о конфиденциальности при наличии поддержки РЗР Первый шаг на пути к созданию информационного наполнения РЗР — созда ние файла ссылки на политику. Этот файл указывает на XML-файл политики сай та. Назовите его РЗР^ст! и храпите в каталоге W3C, расположенном в корневом каталоге Web-сайта. Например, файл ссылки на политику Microsoft находится по адресу http://www.microsqft.com/w3c/p3p-xml. Вот пример такого файла:</p><p> ГЛАВА 22 Обеспечение конфиденциальности <МЕТА xmlns="http://www.w3.org/2000/12/p3pv1"> <POLICY-REFERENCES> <POLICY-REF about="Policy.xml"> <INCLUDE>\*</INCLUDE> <COOKIЕ-INCLUDE name="*" value="*" dofnain="." path="*"/> </POLICY-REF> </POLICY-REFERENCES> </META> Пытаясь отобразить политику конфиденциальности Web-сайта, Internet Explo rer 6 просматривает каталог W3C Web-сайта, обнаруживает файл РЗР.хт!, считы вает содержимое T3r3.POUCY-REF, где указано местоположение XML-версии фай ла политики конфиденциальности сайта. Это второй файл, который требуется создать. Он содержит сжатую версию общей политики конфиденциальности, Ниже приведен пример XML-версии политики конфиденциальности. Атрибут discuri указывает на полную политику конфиденциальности W7eb-caUTa. Его мож но вызвать из Internet Explorer 6 с помощью ссылки here. Остальные поля файла разбирает Internet Explorer 6 и отображает результат в окне отчета. Блок опера торов в конце файла описывает конфиденциальность для Web-сайта и определя ет, какие манипуляции выполняются с данными. В этом примере два заявления о конфиденциальности. В первом говорится о ведении журнала на Web-сайте и сохранении стандартной информации, в том числе типа браузера. Данные хра нятся для целей администрирования и разработки и используются владельцем сайта только для указанных целей. Исчерпывающее описание остальных полей вы най дете на сайте http://www.w3.org РЗР.</p><p> <POLICY xmlns="http://www.w3.org/2000/12/p3pv1" discuri="policy.htm" opturi="http://msdn.microsoft.com/privacy"> <ENTITY> <DATA-GROUP> <DATA ref="tfbusiness.name">Microsoft</DATA> <DATA ref="(fbusiness.contact-info.postal.street">0ne Microsoft Way </DATA> <DATA ref="#business.contact-info,postal.city">Redmond</DATA> <DATA ref="ffbusiness,contact-info.postal.stateprov">WA</DATA> <DATA ref="#business.contact-info,postal.postalcode">78052</DATA> <OATA ref="ebusiness.contact-info,postal.country">USA</DATA> <DATA ref="ftbusiness.contact-info.online.email">michaeL</DATA> <DATA ref="ftbusiness.contact-info.telecom.telephone.intcode"> </DATA> <DATA ref="ebusiness.contact-info.telecom.telephone.loccode"> </DATA> <DATA ref="ffbusiness.contact-info.telecom.telephone.number"> B828080</DATA> </DATA-GROUP> </ENTITY> <STATEMENT> <PURPOSE> Часть IV Особые вопросы <RECIPIENT><ours/X/RECIPIENT> <RETENTIONXstated-purpOSe/X/RETENTION> <DATA-GROUP> <DATA ref="#dynamic.clickstream.serve г"/> <OATA ref="ffdynamic.http.useragent"/> </DATA-GROUP> </STATEMENT> <STATEMENT> <PURPOSE><pseudo-analysis required="opt-in"/x/PUHPOSE> <RECIPIENTXother-recipient/X/RECIPIENT> <RETENTIQNXindefinitely/X/RETENTION> <DATA-GROUP> <DATA ref="ttijser. home-info, postal.postalcode"> <CATEGORIESXdemographic/x/CATEGORIES> </DATA> </DATA-GROUP> </STATEMENT> </POLICY> Файл может храниться в любом месте Web-сайта, при этом необходимо, что бы он упоминался в файле ссылки. При наличии этих двух файлов Internet Explo rer 6 отобразит вашу политику в диалоге отчета при выборе команды Privacy Report в меню View. Рекомендуется создать полную политику конфиденциальности Web сайта. Как это сделать, вы узнаете на сайте TRUSTe (http://www.truste.org/bus/pubj-e sourceguide.html\ nmcujiM.mu.-.ia.icj.i.</p><p> : пате and i fOjtom lisadfr vdue,..</p><p>...</p><p> •/«aeta,-. • itnltrTPhJMifcr, ! CP-"N01 ODM DEV OUR I3TP f-У 'jir. It ' I 'I I Рис. 22-7. Установка компактной политики средствами консоли Internet Information Services (US) Последний элемент этой мозаики — создание компактной политики. Это то.</p><p> посредством чего Internet Explorer 6 определяет, надо ли показывать значок кон фиденциальности в строке состояния. Компактная политика — это «выжимка* полной XML-политики, в которой используются коды, определенные в специфи кации РЗР. (Подробнее — на сайте http://www.w3.org/TR/P3P/ttcompact_poHcies). На рис. 22-7 показана компактная политика для приведенной выше XML-страницы.</p><p> Обеспечение конфиденциальности ГЛАВА 22 По завершении создания компактной политики реализацию РЗР можно считать законченной. Полное описание процесса реализации и развертывания РЗР на Web сайте вы найдете на странице (http://msdn.microsoft.com/workshop/security/pnvacy/ overview/createp rivacypolicy.asp).</p><p> Примечание Internet Explorer 6 подавляет проверку РЗР для сайтов интрасети.</p><p> Конфиденциальность в клиентских приложениях Создавая клиентские приложения, записывающие информацию о пользовате. те, напишите заявление о конфиденциальности, в котором изложите, как планиру ется использовать собранные данные. Предоставьте пользователям возможность настраивать их индивидуальные параметры конфиденциальности. Например, можно запрашивать у пользователя регистрационную информацию или отправ лять данные на Web-сайт, чтобы загрузить определенные данные для приложения.</p><p> Следует так сконфигурировать меню Help (Справка), чтобы облегчить пользона телям доступ к командам управления конфиденциальностью. Если вместе с при ложением предостаааяется набор инструментальных средств разработки (software development kit, SDK), команда меню Privacy Policy (Политика конфиденциально сти) может указывать на документ, ссылка на который есть в реестре или, еще лучше, на политику конфиденциальности на Web-сайте. Пункт меню Privacy Settings (Па раметры конфиденциальности) вызывает интерфейс в DLL, которую реализует программист, применяющий SDK.</p><p> На рис. 22-8 показано диалоговое окно с параметрами конфиденциальности в Microsoft Windows Media Player 9 beta, которое отображается при первом запус ке приложения.</p><p> fe!.:e,e n-.-li rfirinjhnn F-om the Internet fa :. arid Г-И ;</p><p> [;</p><p> 5т1аг«ол)Цйувг-3* to sorter* provid Рис. 22-8. Пример диалогового окна Privacy Options До сих пор я приводил примеры, где предполагалось, что приложение соби рает персональную информацию от имени компании. А что если приложенче собирает данные, которое его пользователи получают от своих клиентов? Так происходит в CRM-системе. Пользователи приложения скорее всего получают контактную информацию от их клиентов. Как им определить, согласны ли юш Часть IV Особые вопросы енты на переписку по электронной почте? На этот случай можно добавить диа логовое окно настройки параметров конфиденциальности — пользователи смо гут хранить информацию о предпочтениях, касающихся конфиденциальности своих клиентов, в той же базе данных (рис. 22-10).</p><p> First name: j Robert Last name: I Brown Privacy ElttaH: |rabbcffilacalhosl.:;</p><p>/?</p><p> Security Address: ] 1234 Main Stre?t City: Jwoodinvie Company: I Global Widgets Conglomerated • &®&**"9- jdesbr Sates tegiom I^Jthwest ] P Encrypt data Рис. 22-9. Диалоговое окно сбора данных о пользователе с возможностью настройки параметров конфиденциальности W I «iB accept emai contact for:</p><p> ^ Account management Privacy Pofcy Г" New product jnformatbn Г Marketing campaigns P You may contact me by phone p1 Vou mgy contact me by U.S. mail f You trey share my contact information with thitdparttes I™ You may tag my non-trarsacttontf actiyltes For prcdud: I Рис. 22-10. Пример диалогового окна с параметрами конфиденциальности Анонимность Многие приложения отслеживают открытые вами файлы, Web-страницы, которые вы посетили, или просмотренные или прослушанные файлы мультимедиа. А что если пользователь не хочет, чтобы эта информация куда-то записывалась, или желает иметь возможность стереть ее в любой момент?</p><p> Представьте себе, что вы ярый фанат футбольной команды «Детройтские львы», которая в этом сезоне проигрывает матчи один за другим, и после каждой игры вы бегаете по всему дому и истерично вопите. Домочадцам осточертели ваши ГЛАВА 22 Обеспечение конфиденциальности переживания, и они решили изолировать вас от футбола. Никакого телевизора, никакого Интернета, никаких звонков от друзей с соболезнованиями. И тут вы узнаете, что «Львы» взяли кубок США! (Повторяю: это исключительно гипотети ческая ситуация!) И вот поздно ночью, когда все улеглись спать, вы крадетесь в подвал, заходите на Web-сайт «Львов», скачиваете потоковое видео последней игры, заходите в чат и оживленно обсуждаете победу со своими друзьями. Вдруг разда ются шаги — это заподозрившая неладное жена. Тут как нельзя кстати функция, позволяющая стереть все лишнее одним щелчком специальной кнопки: закроют ся все приложения и откроется пасьянс — полная иллюзия совершенно безобид ного времяпрепровождения.</p> <div class="po5"></div> <div class='stranici1'><b class='temiser'>Pages:</b>     |<a class="kn1" href="/1/119510-1-michael-howard-david-leblank-writing-secure-code-second-edition-microsoft-press-maykl-hovard-devid-leblank-zaschischenniy-kod-2.php" title=""> 1 </a>|   ...   |<a class="kn1" href="/1/119510-8-michael-howard-david-leblank-writing-secure-code-second-edition-microsoft-press-maykl-hovard-devid-leblank-zaschischenniy-kod-2.php" title=""> 8 </a>|<a class="kn1" href="/1/119510-9-michael-howard-david-leblank-writing-secure-code-second-edition-microsoft-press-maykl-hovard-devid-leblank-zaschischenniy-kod-2.php" title=""> 9 </a>|<div class='kr'><a class="kn1" href="/1/119510-10-michael-howard-david-leblank-writing-secure-code-second-edition-microsoft-press-maykl-hovard-devid-leblank-zaschischenniy-kod-2.php" title=""> 10 </a></div>|<a class="kn1" href="/1/119510-11-michael-howard-david-leblank-writing-secure-code-second-edition-microsoft-press-maykl-hovard-devid-leblank-zaschischenniy-kod-2.php" title=""> 11 </a>|<a class="kn1" href="/1/119510-12-michael-howard-david-leblank-writing-secure-code-second-edition-microsoft-press-maykl-hovard-devid-leblank-zaschischenniy-kod-2.php" title=""> 12 </a>|</div> <div class="separator2"></div> <div class="po122"> <img class="doc" src="/images/doc.gif" border="0" alt="" ><a class="menusil" href="/1/" title=""><b class="jir">Книги, научные публикации</b></a> </div> <div class="niz2"> <br><br> <noindex> <center> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- dislib-kvadrat (niz) --> <ins class="adsbygoogle" style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-9894471784993021" data-ad-slot="3110193131"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </center> </noindex> <br> <div class="naverh"><A href="#verh" >наверх</a><img src="/images/s.gif" hspace="3" width="5" height="11" border="0" alt="" align="top" vspace="3" ></div> </td></tr></table> <table width="100%" cellspacing="0" cellpadding="0" border=0> <tr> <td bgcolor="#CCCCFF" height="1"> </td> </tr> <tr> <td class="menu-niz"> <center> <table cellspacing="0" cellpadding="0" border=0> <tr> <td class="menu-niz1"> |  • <a href="/" title="На главную">Главная</a>  |  • <a href="/admin/contact-kontakti-dissertatsii.php" title="Контакты">Контакты</a> |  </td> </tr> </table> </center> </td> </tr> <tr><td class="line1"></td> </tr> </table></td><td class="line"><img class="lin" src="/images/spaser1.gif" border="0" alt=""></td></tr></table> </td><td valign="top"> <table width="5" border="0" cellspacing="0" cellpadding="0"> <tr> <td></td></tr></table></td></tr></table> </td><td class="site2"></td></tr><tr><td colspan="3"> <noindex> <script type='text/javascript' src='http://recreativ.ru/rcode.97536708c5.js'></script> <script type='text/javascript' src='http://recreativ.ru/rcode.88aa634d1b.js'></script> <script type='text/javascript' src='http://recreativ.ru/rcode.30746632cd.js'></script> </noindex> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td valign="top" class="cap1"> <font color="#808080">© 2011 www.dissers.ru - «Бесплатная электронная библиотека»<br><br> <noindex> Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам. <br> Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, <a href="/admin/contacts.php" title="">напишите нам</a>, мы в течении 1-2 рабочих дней удалим его. </noindex> </font> </div> </td> </tr> </table> <noindex> <!-- Yandex.Metrika counter --> <script src="//mc.yandex.ru/metrika/watch.js" type="text/javascript"></script> <script type="text/javascript"> try { var yaCounter78166 = new Ya.Metrika({id:78166,type:1}); } catch(e) { } </script> <noscript><div><img src="//mc.yandex.ru/watch/78166?cnt-class=1" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter --> </noindex></td></tr></table> </body> </html>