Проблемы безопасности нужно рассматривать одновременно с нескольких точек зрения. Во-первых, вы не можете быть уверены, что все модули надежны. В предыдущем разделе я рассказывал о «вредных» программах; возможно, что один или несколько модулей являются разрушительными или просто неисправными. Во-вторых, вы не должны допускать, что все модули написаны настолько хорошо, что будут работать во всех возможных конфигурациях. Достоинством крупных компьютерных программ было то, что они тестировались как единое целое. Браузер, работающий на вашем компьютере, со всеми дополнительными модулями, которые вы загружали в произвольном порядке, может быть совершенно уникален. Маловероятно, что это сочетание кто-то уже тестировал.
И в-третьих, еще не существует такой операционной системы, которая помогла бы решить две вышеуказанные проблемы. При старом принципе построения программ различные части программного обеспечения сообщались только через операционную систему. Хорошая операционная система могла обеспечивать взаимодействие программ и не допускать, чтобы одна программа повреждала другую. Современные компоненты непосредственно обращаются друг к другу, без посредничества операционной системы, поэтому применяемые в последних меры безопасности могут не работать.
Эти проблемы безопасности пытались решать с применением некоторых общих методов, одни из которых принесли больший, другие – меньший успех. Но все эти подходы лучше выглядят в теории, чем работают на практике.
Автономность (Isolation) и защита памяти.Эта мера направлена на то, чтобы помешать одному из компонентов умышленно или случайно воздействовать на остальную систему: читать или вносить изменения в память другого компонента, выходить за пределы отведенной ему памяти и приводить к поломке системы или доставлять другие неприятности. Автономное использование памяти предполагает, что каждому компоненту отводится свой участок памяти, за пределами которого этот компонент не может ни читать, ни записывать. Время от времени контролирующие программы (program checkers), установленные на машине пользователя, проверяют коды компонентов, чтобы убедиться, что не происходит ничего недозволенного. Примером реализации этой идеи служит «песочница» (sandbox) Java: все компоненты вынуждены «играть» в отдельных «песочницах», из которых они не могут повредить друг друга. Этот принцип защиты работает хорошо, но некоторые ошибки он не позволяет обнаружить, кроме того, за него приходится расплачиваться скоростью работы программ.
Контроль доступа в интерфейсе.Сделав компонент полностью изолированным, мы не решаем проблему полностью: ведь ему необходимо взаимодействовать с другими компонентами (а также с экраном, клавиатурой, мышью и т. д.). На рис. 10.2 показаны пути взаимосвязей между компонентами. Устанавливая правила контроля доступа в точках соприкосновения, мы можем надеяться, что компоненты правильно взаимодействуют друг с другом. Проблема в том, что вы должны выбрать политику контроля доступа, которая должна быть достаточно жесткой, чтобы приносить действительную пользу. «Песочницы» Java позволяют добиться хороших результатов, однако недостаток их политики состоит в том, что она либо чересчур бескомпромиссная, либо излишне либеральная – «золотой середины» в реальности не существует. (Java 2 имеет мелкомодульный контроль, но он недостаточно используется.)
Подписывание кода (Codesigning).Представьте себе закрытую частную вечеринку, попасть на которую реально, только предъявив какой-нибудь солидный документ (например, водительские права). При таком подходе в дом смогут пройти только друзья хозяина. Такой же смысл имеет подписывание кода. Программист подписывает отдельные компоненты. На основании этих подписей пользователь принимает решение, какие компоненты допустить на свой компьютер, а какие – нет. (В случае ActiveX подписывание кода – основной способ защиты от злонамеренного кода.) В своем сегодняшнем виде подписывание кода имеет массу проблем. Во-первых, непонятно, исходя из каких соображений пользователь должен решать, заслуживает ли доверия автор подписи. Во-вторых, сам факт существования подписи у компонента не означает, что он безопасен. В-третьих, то, что каждый из двух компонентов имеет подписи, не означает, что их можно использовать вместе: совместная работа чревата множеством непредвиденных опасных ситуаций. В-четвертых, к проблеме безопасности не следует подходить с позиции «все или ничего»: существуют разные степени безопасности. И в-пятых, фиксирование компьютером нападения (сохранение подписи кода) практически бесполезно с точки зрения атаки: при ее осуществлении злоумышленник может удалить или изменить подпись или просто переформатировать диск, на котором она была сохранена. Чем больше приходится размышлять о подписывании кода, тем меньше смысла видится в этой процедуре.
Читать дальше