Wiki-учебник по веб-технологиям: JavaScript/ПолитикаОдногоИсточника ...

Главная | Каталог |

Использование маркированных скриптов


Модель безопасности JavaScript для маркированных скриптов базируется на модели безопасности Java для маркированных объектов. Вы можете маркировать инлайн-скрипты (те, которые находятся в тэгах SCRIPT), скрипты в обработчики событий, объекты/entities JavaScript и отдельные JavaScript-файлы.

JavaScript 1.1 и более ранние версии. Маркировка скриптов отсутствует.

Маркированные скрипты. Введение.


Маркированный скрипт запрашивает расширенные привилегии, получая доступ к закрытой информации. Он запрашивает эти привилегии через использование LiveConnect и Java-классов, называемых Java Capabilities API. Эти классы добавляют возможности и уточняют управление, предоставляемое стандартным Java-классом SecurityManager. Вы можете использовать эти классы для осуществления высокоточного контроля в так называемом «sandbox/песочном ящике» – термин Java для жёстких ограничений, в пределах которых код Java обязан выполняться.

Решения по управлению доступом сводятся к тому, кто и что может делать. В этой модели principal\принципал представляет «кто», target\цель представляет «что», а privileges\привилегии, ассоциированные с принципалом, представляют авторизацию (или запрет авторизации) принципалу для доступа к специфической цели.

После написания скрипта вы маркируете его, используя утилиту Netscape Signing Tool. Эта утилита ассоциирует цифровую подпись со скриптом на HTML-странице. Владельцем это цифровой подписи является определённый принципал (реальный объект, такой как Netscape или John Smith). Одна HTML-страница может иметь скрипты, маркированные разными принципалами. Цифровая подпись помещается в Java Archive (JAR) -файл. Если Вы маркируете инлайн-скрипт, обработчик события или объект JavaScript, Netscape Signing Tool сохраняет только подпись и идентификатор для скрипта в JAR-файле. Если вы маркируете JavaScript-файл утилитой Netscape Signing Tool, она также сохраняет источник в JAR-файле.

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

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

В этой главе предполагается, что вы знакомы с основными принципами маркировки объектов с использованием Java Capabilities API и с созданием цифровой подписи. Следующие документы содержать соответствующую информацию по этому вопросу:


SSL-серверы и немаркированные скрипты

Альтернативой маркировке ваших скриптов утилитой Netscape Signing Tool является обслуживание их сервером безопасности/secure server. Navigator рассматривает все страницы, обслуживаемые SSL-сервером, как если бы они были маркированы ключом public такого сервера. В этом случае вам не нужно маркировать отдельные скрипты.

Если вы имеете SSL-сервер, то вам будет намного проще организовать работу ваших скриптов как маркированных. Это особенно актуально, если вы динамически генерируете скрипты на вашем сервере и хотите, чтобы они работали как маркированные.

SSL-серверы и немаркированные скрипты


Альтернативой маркировке ваших скриптов утилитой Netscape Signing Tool является обслуживание их сервером безопасности/secure server. Navigator рассматривает все страницы, обслуживаемые SSL-сервером, как если бы они были маркированы ключом public такого сервера. В этом случае вам не нужно маркировать отдельные скрипты.

Если вы имеете SSL-сервер, то вам будет намного проще организовать работу ваших скриптов как маркированных. Это особенно актуально, если вы динамически генерируете скрипты на вашем сервере и хотите, чтобы они работали как маркированные.

Принципалы кодовой базы


Как и Java, JavaScript поддерживает принципалы кодовой базы/codebase principals. Принципал кодовой базы это принципал, полученный из источника скрипта, а не при проверке цифровой подписи сертификата. Поскольку принципалы кодовой базы обеспечивают слабую защиту, они по умолчанию отключены в Navigator'е.

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

Чтобы включить принципалы кодовой базы, конечные пользователи обязаны добавить соответствующую настройку в файл настроек Navigator'а. Для этого нужно добавить в файл настроек такую строку:

user_pref("signed.applets.codebase_principal_support", true);


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

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

ПРИМЕЧАНИЕ: Если страница маркированные скрипты и codebase-скрипты и поддержка принципалов кодовой базы signed.applets.codebase_principal_support включена, все скрипты на этой странице рассматриваются как немаркированные, и применяются принципалы кодовой базы.

Скрипты, маркированные разными принципалами


JavaScript отличается от Java в нескольких важных вопросах, касающихся безопасности. Java маркирует классы и может защищать внутренние методы этих классов через механизм public/private/protected. Маркировка метода как protected или private немедленно защищает его от атак извне. Кроме того, любой класс или метод, помеченный как final в Java, не может быть расширен и таким образом также защищён от вторжения.

С другой стороны, поскольку в JavaScript нет понятия public и private-методов, отсутствуют и внутренние методы, которые могут быть защищены простой маркировкой класса. Кроме того, все методы могут изменяться на этапе прогона программы, поэтому обязаны быть защищены и на этапе прогона.

В JavaScript вы можете добавить новые свойства к существующим объектам или заменить существующие свойства (включая методы) на этапе прогона. Вы не может сделать это в Java. Итак, ещё раз, защита, которая автоматизирована в Java, обязана обеспечиваться в JavaScript отдельно.

Поскольку модель маркировки скриптов в JavaScript основана на модели маркировки объектов Java, указанные отличия языков означают, что, если скрипты JavaScript произведённые разными принципалами, взаимодействуют, необходимо более надёжно защитить эти скрипты. Поскольку весь код JavaScript на одной странице HTML запускается в одном процессе, скрипты, находящиеся на одной странице могут изменять поведение друг друга. Например, скрипт может переопределить функцию, определённую в другом скрипте ранее на этой же странице.

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

Например, принципалы A и B маркировали один скрипт, но только принципал A маркировал второй скрипт. В этом случае страница с обоими скриптами работает так, как если бы была маркирована только принципалом A.

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

Вы можете использовать функции import и export, чтобы разрешить скриптам, маркированным разными принципалами, взаимодействовать в безопасном режиме.

Проверка принципалов окон и слоёв


Чтобы защитить маркированные скрипты от изменений, JavaScript имеет набор для проверки на уровне контейнера, где контейнером является окно или слой. Для доступа к свойствам маркированного контейнера, скрипт, ищущий доступ, обязан быть промаркирован супернабором принципалов, которым маркирован контейнер.

Эта межконтейнерная проверка применяется для большинства свойств, предопределённых (Navigator'ом) или пользовательских (содержимого HTML или функций и переменных скриптов). Межконтейнерная проверка не применяется для следующих свойств объекта window:


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



Этот метод работает так: каждый скрипт на странице рассматривается в порядке определения, javascript: URL'ы считаются новыми немаркированными скриптами.

1. Если это первый скрипт на странице, принципалы этого скрипта присваиваются окну как принципалы. (Если текущий скрипт является немаркированным, это делает принципалы окна принципалами кодовой базы.) Выполнено.
2. Если самый внутренний контейнер (контейнер, непосредственно содержащий скрипт) имеет определённые принципалы, выполняется пересечение принципалов текущего скрипта с принципалами контейнера и результат присваивается как принципалы контейнера. Если эти два набора принципалов не равны, их пересечение уменьшает количество принципалов, ассоциированных с этим контейнером. Выполнено.
3. Иначе ищется самый внутренний контейнер, имеющий определённые принципалы. (Это может быть само окно, если нет промежуточных слоёв.) Если принципалы текущего скрипта такие же, что и принципалы этого контейнера, принципалы остаются как есть. Выполнено.
4. Иначе принципалы текущего скрипта присваиваются как принципалы контейнера. Выполнено.

Например, предположим, что на странице имеются два скрипта (и нет слоёв), один скрипт маркирован, а другой – нет. Navigator сначала просматривает маркированный скрипт, что ассоциирует объект window с двумя принципаламипринципалом сертификата от маркировщика скрипта и принципалом кодовой базы, полученным из location страницы, содержащей скрипт.

Когда Navigator видит второй (немаркированный) скрипт, он сравнивает принципалы скрипта с принципалами текущего контейнера. Немаркированный скрипт имеет только один принципал кодовой базы. При отсутствии слоёв самым внутренним контейнером является само окно, которое уже имеет принципалы.

Поскольку наборы принципалов различны, они пересекаются, давая набор с одним членом, принципалом кодовой базы. Navigator сохраняет результат в объекте window, уменьшая его набор принципалов. Заметьте, что все функции, которые были определены в маркированном скрипте, рассматриваются теперь как немаркированные. Отсюда, смешивание маркированных и немаркированных скриптов на одной странице без слоёв приводит к тому, что все скрипты рассматриваются как непомеченные.

Теперь предположим, что немаркированный скрипт находится в слое на странице. Это даст иное поведение. В этом случае, когда Navigator видит немаркированный скрипт, принципалы скрипта вновь сравниваются с принципалами маркированного скрипта окна и определяется, что принципалы различны. Однако теперь самый внутренний контейнер (слой) не имеет ассоциированных принципалов, немаркированные принципалы ассоциированы с самым внутренним контейнером; внешний контейнер (окно) не затрагивается. В этом случае маркированные скрипты продолжают действовать как маркированные. Однако доступ немаркированного скрипта слоя к объектам вне слоя отбрасываются, поскольку слой имеет недостаточно принципалов.