Безопасность. Модификация Основного Кода Платформы С Помощью Загружаемых Апплетов.

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

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

А в активном блоке невнимательный разработчик (злоумышленник) может получить доступ к глобальному объекту окна и получить доступ к переменным или важным методам ядра и произвести подмены, что в лучшем случае просто приведет к краху платформы (внутри браузера, разумеется).

), а в худшем – установку различных хуков, не влияющих на работу системы, но перехватывающих персональные данные пользователя.

В будущем ничего не подозревающий пользователь будет использовать гаджет «Часы от Боба», который незаметно собирает о нем информацию или рассылает спам на адреса из списка контактов.

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

Всем известно, что когда переменная создается в глобальном пространстве имен, она становится свойством объекта окна.

Например, вар а = 10; то же самое, что и window.a = 10; Наша задача — изолировать код ядра, чтобы сторонние скрипты не могли получить к нему доступ.

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

Пример: (function () { a = 10; })(); Функция анонимна и не будет видна через объект окна.

Давайте создадим простое ядро:

вар Core = {}; Core.sName = "MyCore"; Core.MyMethod = function(sMyValue) { alert(sMyValue); };* Этот исходный код был выделен значком Выделение исходного кода .

Изолируем ядро:
(функция(){ вар Core = {}; Core.sName = "MyCore"; Core.MyMethod = function(sMyValue) { alert(sMyValue); }; })();* Этот исходный код был выделен значком Выделение исходного кода .

Теперь давайте создадим функцию загрузки апплета: Applet.Link = function(sCode, oContext) { (новая функция(sCode)).

call(oContext); }, Где sCode — исполняемый код апплета, oContext — важный параметр.

Если посмотреть шире, это концепция контекста из мира настольного программного обеспечения.

Те, кто писал на ассемблере в защищенном режиме, поймут, о чем речь.

Короче говоря, контекст содержит информацию о состоянии системы.

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

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

В нашем случае контекст содержит переменные и объекты платформы, необходимые для работы апплета.

Наша задача — сформировать контекст при запуске апплета на исполнение.

Для этого нам нужно знать, какие переменные и методы платформы необходимы коду апплета.

Мы будем рассматривать уже созданные объекты.

Допустим, апплету нужен метод MyMethod из пространства имен Core. Контекст будем создавать вручную (в Hyper это все автоматизировано, есть дескриптор апплета в формате xml и концепция ImportBlock, где перечислены импортированные переменные и объекты).

В этой статье все упрощено, чтобы помочь вам понять материал.

Итак, мы получаем контекст: var oContext = {MyMethod: Core.MyMethod) }.

Давайте объединим все это в коде:

(функция() { // Основной модуль.

вар Core = {}; Core.sName = "MyCore"; Core.MyClass = function() {}; Core.MyClass.prototype.MyMethod = function(sMyValue) { alert(sMyValue); }; // Модуль апплета.

Апплет = {}; Applet.Link = function(sCode, oContext) { (новая функция(sCode)).

call(oContext); } // Загружаем модуль апплета.

var sCode = "this.MyMethod('Привет, мир');"; вар oContext = {MyMethod: Core.MyMethod}; Applet.Link(sCode, oContext); })();* Этот исходный код был выделен значком Выделение исходного кода .

Что происходит в полученном коде? Апплет создается с помощью кода: this.MyMethod('Hello world'); Поскольку функция с этим кодом была запущена в контексте объекта oContext, содержащего свойство MyMethod, через this это свойство становится доступным в теле этой функции.

Апплет отобразит предупреждение с текстом «Привет, мир».

Вернемся к злоумышленникам или просто невнимательным разработчикам.

Апплет №1 был создан с кодом и запущен на выполнение:

this.MyMethod = function() { alert("Hack!!!") }; this.MyMethod('Hello world!!!');* Этот исходный код был выделен значком Выделение исходного кода .

В результате этот апплет покажет предупреждение с текстом Hack. Апплет пытается заменить метод из пространства имен Core, но на самом деле он меняет только метод в его контексте.

И поэтому другой апплет, использующий тот же метод, будет работать нормально.

Апплет №2 с кодом был создан и запущен: Core.MyMethod = function() { alert('Hack!!!'); }; Здесь злоумышленник явно попытался изменить Core.MyMethod, но его апплет потерпит неудачу, поскольку Core не определен, и мы знаем почему.

А теперь весь код:

(функция() { // Основной модуль.

вар Core = {}; Core.sName = "MyCore"; Core.MyMethod = function(sMyValue) { alert(sMyValue); }; // Модуль апплета.

Апплет = {}; Applet.Link = function(sCode, oContext) { (новая функция(sCode)).

call(oContext); }; // Загружаем модуль апплета от хакера №1. var sCode = "this.MyMethod = function() { alert('Hack!!!'); }; this.MyMethod('Hello world');"; вар oContext = {MyMethod: Core.MyMethod}; Applet.Link(sCode, oContext); // Загружаем модуль апплета от хакера №2. var sCode = "Core.MyMethod = function() { alert('Hack!!!'); };"; вар oContext = {MyMethod: Core.MyMethod}; Applet.Link(sCode, oContext); // Загрузите модуль апплета от нужного разработчика.

var sCode = "this.MyMethod('Привет, мир');"; вар oContext = {MyMethod: Core.MyMethod}; Applet.Link(sCode, oContext); })(); * Этот исходный код был выделен значком Выделение исходного кода .

ВАЖНЫЙ!!! При создании контекста нужно следить, чтобы туда не попала никакая ссылка на объект, иначе вредоносный апплет сможет подменить весь объект методами и вся платформа будет работать с вредоносным кодом.

Проблема решается написанием функции формирования контекста, которая учитывает всё импортируемое и копирует его по иерархии объектов.

Заключение: Рассмотрена вторая проблема безопасности платформы, имеющей возможность разработки для нее апплетов.

Первый из них, напомню, это конфликты имен переменных в глобальном пространстве имен .

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

), но это тема для другой статьи.

Теги: #JavaScript #core #applet #security #JavaScript

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.