Pull to refresh

Comments 53

Сорри уже в третий раз забыл. Все сделал.
А как всеже это решает проблему безопасности? Как я понимаю те же cookies своровать это не мешает, отправить любые данные из dom тоже. Так зачем злоумышленнику вообще заменять код ядра?
Изменить может не только злоумышленник, но и разработчик по невнимательности. "Есть еще третья проблема это доступ к глобальным свойствам браузера (window, document и т.д.), но эта тема для другой статьи."
Счастливый обладатель FF2 пишет что то вроде
var sCode = "eval('alert(Core.sName);',arguments.callee.caller);";
и получает доступ к ядру системы :)

FF2 позволяет выполнять код в произвольном контексте, в данном случае в контексте метода Link для которого ядро доступно.

Имхо, невозможно создать защищенный код в JavaScripte, проще иметь здоровую параною и не доверять ничему что приходит с клиентской стороны.
Серьезное замечание. Но чем более он защищен тем меньше вероятность появления вредоносного скрипта. Пока на ум приходит предварительная проверка кода на поиск таких конструкций, например регулярными выражениями.
код можно элементарно пошифровать
когдато решал эту проблему
самая реальная защита при необходимости запускать чужой javascript это запуск скриптов в разных доменах.
тоесть, есть main.siteurl.com и runner.siteurl.com
Страница запускается на субдомене main и в iframe подгружает страницу с runner.
Скрипты могут обмениваться данными через специальные куки с доменом .siteurl.com
и только данными, никакого кода естественно. Таким образом вражеские скрипты не могут иметь доступа к основному коду и к кукам пользователя на main.
eval вообще нужно запретить, время уже играет не в пользу этой функции, от нее отказываются разработчики, второе вопросы безопасности клиентского кода станут острее когда количество платформ для разработки приложений увеличится и они будут занимать значительную часть инета. А eval мое мнение это серьезная брешь в безопасности клиентского кода.
eval это такой-же метод javascript-a как и другие, никакого вселенского зла в нем нет, и даже если заблокировать сам eval остаются альтернативные варианты ( setTimeout, execScript[IE] )
В коде статьи используется "new Function" - этот же тот самый eval только вид сбоку.
Прошу прощения за занудство, но "В кратце" пишется слитно.
слово applet тут не совсем пляшет, я как Java программер привык асоциировать applet с Java-applet, долго вьезжал где же тут Java, а вообще еще не мешалобі переопределиь eval, положив "за щеку оригинальную функцию", и в дальнейшем внутри переопределенной проверять что на вход подается.
Да Eval надо контроллировать, проверять на входные параметры и вызывать родной eval уже если все нормально. Например проверять на контекст, если запуск кода производится в контексте функций которые знают о ядре - останавливать запуск.
Тоже не решит всей проблемы. Если оригинальный eval не доступен, можно создать новый ифрейм и воспользоваться eval-ом новосозданного окна.
Ирфейм вообще опасная штука. Для апплетов он вообще не нужен чтобы код разработчика его создавал. По сути проблему как с eval так и другими нативными методами и объектами браузера решается на уровне третьей проблемы о которой уже упоминал в статье. Решение будет базироваться на подмене глобальных объектов и методов в коде апплета.
Хммм.. Это только у меня ошибка в ФФ3 выскакивает?


защита в действии :)
Permission denied to get property Element.childNodes
UFO just landed and posted this here
Обёртка кода очень полезна для того, чтобы различные скрипты не конфликтовали друг с другом но говорить в данном контексте о безопасности в глобальном смысле какбе некорректно. Если злоумышленник получил доступ к браузеру пользователя, то наличие скриптов, их отсутствие или вот такая обёртка уже ни на что не влияют.
В глобальном смысле безопасности достигнуть нереально. Но всегда можно уменьшить количество лазеек, например, не все предложили решение доступа к ядру: eval('alert(Core.sName);',arguments.callee.caller); В принципе это сделал только один человек, а чем меньше лазеек тем лучше.
Здесь рассматривается именно вариант(хотя полностью не решен, будем ждать следующей статьи ;)), когда сервис предоставляет возможность сторонним разработчикам загружать их скрипты(апплеты) под управлением единого "ядра". Цель защиты, чтобы именно такой скрипт не оказался закладкой, способной перехватить вызовы "ядра". И именно такой скрипт не должен получить доступ к базовым элементам ДОМ браузера.
Ну вызовы ядра мы ограничим, но как вы планируете ограничивать возможности браузера? Лично я не представляю...
Конечно. Но смотрите в чем особенность. Это функционал по своей сути ядра(модуль загрузки апплетов). В функции безопасности ядра входит защита своей целостности! Это очень важно, так как доступ будет не только к машине пользователя, если произойдет подмена и нарушения целостности ядра, но и к центральному хранилищу.

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

К тому же не забывайте такую приятную мелочь как тот факт, что все JS скрипты выполняются в одном контексте в браузере и могут прототипировать любые обьекты. Умелому программеру хватит ума расширить функционал прототипов Function и Object чтобы получить полный доступ к вашему Core. Так что я не совсем понимаю смысл заниматься танцами с бубном.
Смысл в том что бы в какой то степени обезопасить. Меньше лазеек лучше, чем много лазеек. Темболее что инфраструктура для разработки и развертывания веб-приложений не просто в веб переносится, а в платформы обеспечивающие их функционирование и взаимодействие. И вопросы безопасноти становятся актуальными.
Это я понимаю, но JS слишком похож на глину - что хошь, то и делай и ничто этому не преграда...

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

И ещё один совет. Вы же даёте (или будете давать) программерам какой-то API. А также возможность добавлять их код в ваш проект через некую централизованную систему. Думаю на этом этапе можно было бы добавить что-то вроде компилятора, который будет проверять какие обьекты и методы использует код. Взять тот же движок мозиллы, поковырять его, запретить вызовы некоторые и на по результату тестового выполнения сообщать программеру будете ли вы принимать его скрипт или нет.

Наверное можно ещё что-то интересное придумать, но я недавно проснулся, пока туго соображаю...
Вот это офигенная идея. Единственно конечно нужно просчитать хеши для критичных к безопасности функций заранее и важно придумать где хранить хеши чтобы не было подмены. Самый простой вариант хранить хеши в базе и периодически обновлять на клиенте в фоновом режиме.
Извините, даже прочитать статью полностью не успел, но не могу терпеть.
В начале написано: "Все что описано выше..."
Если такое и писать, то в конце топика, в начале пишется "Все что описано ниже..."
Неплохо бы ещё "Applet = {};" заменить на "var Applet = {};", а то вы сами себе создаёте лазейку.
Ага иначе она будет глобальной. Опечатка.
Что-то я запутался при прочтении статьи:
"sCode - исполняемый код апплета, oContext - важный параметр.", а код внизу, через 2 абзаца. Мне кажется, лучше сначала код, а потом пояснение, а не наоборот.
Вот блин. Случайно затер этот кусок кода перед sCode - исполняемый код апплета, oContext - важный параметр
Простите, но это - ерунда. Можно сколько угодно изощряться в создании контекстов и т.п., расписывать красивые классы вроде Applet или Thread, но коду нельзя запретить обращаться к глобальным объектам браузера. И вся защита моментально теряет смысл. В общем, "незачет" - это не защита, а всего лишь размышления на тему того, как было бы хорошо, если бы...
Ну во-первых класс Applet не занимается защитой. Это класс описывающий структуру приложения созданного сторонними разработчиками. Используется для присоединения к среде в которой будет работать. Класс Thread также не занимается защитой. Его цель создавать одно или несколько пространств для выполнения кода. Пример использования - есть апплет карты и вам нужно в информаторе на карте вывести миникарту, делается второй поток и юзаются теже, загруженные скрипты.
Во-вторых коду можно запретить обращаться к глобальным объектам браузера ;)
> Во-вторых коду можно запретить обращаться к глобальным объектам браузера ;)
как? чегото в голову не приходит как ...
Во-первых, я говорил про "классы вроде", имея в виду весь спектр различных ухищрений для изоляции отдельных участков JS-кода.
Во-вторых, поделитесь пожалуйста РАБОЧИМ способом запретить ПРОИЗВОЛЬНОМУ коду обращаться к глобальным объектам браузера (модифицировать DOM, использовать innerHTML) ;)
РАБОЧИЙ пример не будет пока не будет готово то что необхдимо защищать. А если таке интересно возможноли это или нет посмотрите как сделан iGoogle (с его сотнями гаджетов от стронних разработчиков там наверное вообще одни дыры получается?), или пример Facebook platform, когда на страницу можно ставить приложения разработанные 3-ми лицами, которые также могут innerHTML заюзать и таскать конфиденцильную инфу. Но нет эти вопросы решены, скачайте Facebook platform и посмотрите как: http://developers.facebook.com/fbopen/
"РАБОЧИЙ пример не будет пока не будет готово то что необхдимо защищать."
Еще раз - речь идет о запрете доступа к глобальным объектам браузера из произвольного скрипта, подключаемого на странице.

"Посмотрите как сделан iGoogle..."
А при чем тут iGoogle? Там разве декларируется некая "защита от модификации платформы произвольным скриптом"? Нет такого

Прочитайте еще раз название статьи, плиз - и приведите работающий пример защиты. Хорошо?
> Еще раз - речь идет о запрете доступа к глобальным объектам браузера из произвольного скрипта, подключаемого на странице.

В моей статье речь о запрете доступа к глобальным объектам браузера не идет! Читайте внимательней.

> приведите работающий пример защиты. Хорошо?
На создание полноценного secure модуля уйдет не один месяц. Для этого на стороне сервера делается ФИЛЬТР который прогоняет JS код и делает замены (было так: document.getElementById("id"), стало так: HDocument.getElementById("id"), где HDocument отностится к пространству ядра и позволяет брать только те элементы которые были созданы в КОНТЕКСТЕ АППЛЕТА, не разрешает брать чужие элементы. И т.д. так по всем объектам. Сложность состоит в том чтобы предусмотреть множество вариантов входных данных которые могут получить доступ как к глобальным объектам браузера, так и к объектам платформы.
"В моей статье речь о запрете доступа к глобальным объектам браузера не идет!"
Именно поэтому статья вызывает недоумение - без контроля доступа к глобальным объектам защита платформы невозможна. Получается сферический конь - "если злоумышленник не хочет нас ломать, то для защиты мы можем..."

"Для этого на стороне сервера делается ФИЛЬТР который прогоняет JS код и делает замены (было так: document.getElementById("id"), стало так: HDocument.getElementById("id")"
То есть вы предлагаете преобразовать JS в некий Secure Script (это я только что придумал название), и исполнять его в рамках виртуальной машины, написанной на JS? )

"Сложность состоит в том чтобы предусмотреть множество вариантов входных данных"
Сложность состоит в том, что бы написать полноценную вирутальную машину, плюс своего рода "DOM в DOM'е". [b]Но эта тема к JS не имеет никакого отношения[/b], ибо исполняется код на Secure Script. Понимаете?
Какая виртуальная машина? Вы о чем? Платформа предоставляет эти объекты HDocument, HWindow и т.д. Никакой виртуальной машины совершенно. И скрипт работает с этими объектами вот и все. А так как преобразование идет на стадии когда Script еще является текстом и только после преобразование уходит на конструктор Function, то вероятность взлома >>сильно уменьшается.
"Платформа предоставляет эти объекты HDocument, HWindow и т.д"
А что вы будете заменять в этом коде:

(function() {
var x = function(){};
var y = x.constructor;
var a = "win";
var b = "dow.a";
var c = "lert('h";
var d = "ack');";
(new y(a + b + c + d))();
})();

Очевидно, что ссылок на глобальные объекты код в явном виде не содержит - они формируются во время выполнения. И не раньше.
Очень просто. Было сказано что переопределаются объекты и функции, а темболее такие как eval и оператор new. В нашем случае после прохода фильтром мы имеем:

(New(y(a + b + c + d)))(), где New занимается созданием любых новых объектов в платформе, так эта часть y(a + b + c + d) у нас сформириуется во время выполнения, платформа перехватит аргумент поступивший в функцию New, далее этот же аргумент в виде текста проходит фильтр и создается уже объект, в нашем же случае можно сразу пометить такой код как вредоносный и не продолжать работу, так как для разработчиков будут предусмотрены объекты платформы (HWindow, HDocument и т.д.) имеющие тотже интерфейс что и нативные объекты, то если кто то пишет window.alert('Hack') игнорируя предусмотренные объекты, то у него явно нехорошие намерения.
Такой подход в теории может решить проблему но
а) Если предполагается разрешать работу с DOM-ом потребуется создать гигансткое количество врапперов.
б) достаточно добавить к вышенаписанному коду
var New = function(a){return new a;};
и фильтрация идет боком, таких варинатов много - есть масса точек для атаки.
Нужно перехватывать вызовы функций, чтений/установку свойств, и много чего еще ;) Кстати, что делать с зарезервированными словами, которых достаточно много - тупо запрещать их использование? Т.е. alert('check document') автоматически становится вредоносным кодом )
Ну так даже не интересно. Вуаля (слова new нет):
(function() {
var x = function(){};
var y = x.constructor;
var a = "win";
var b = "dow.a";
var c = "lert('h";
var d = "ack');";
(y(a + b + c + d))();
})();

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

Именно такой подход называется виртуальной машиной.
В теории это все решается (в вашем случае фильтруется function и нативный параметр construct).

Но вот это все равно не виртуальная машина. Где в этом подходе вы видите семантический анализ и последующее исполнение P-кода на виртуальной машине (допустим стековой архитектуры) это ничего не было заявлено предлагались только фильтры.
"В теории это все решается (в вашем случае фильтруется function и нативный параметр construct)."
Каким образом фильтруется function? Вы не можете запретить мне создавать функции, равно как и использовать constructor - ибо в этом случае мы говорим уже не о JS, а о чем-то кастрированном.

"Но вот это все равно не виртуальная машина."
Это виртуальная машина - т.к. вам потребуется САМОСТОЯТЕЛЬНО реализовать все стандартные элементы языка, такие как (), new, [] и все-все-все. После чего в рантайме вы производите анализ аргументов, при необходимости преобразуете их в вид понятный браузерному интерпритатору, и отдаете на исполнение.

Или можно сказать по-другому - вы преобразуете JS в некий Safe Script, который потом и исполняется написанным вами интерпретатором.
Да нет никакого итерпретатора. Вы хоть их писали? Я писал с нуля на С++ для С++ like script. А здесь предлагается решение из врапперов оберточных функций), где нативные методы оборачиваются функциями в которых фильтруется входная информация).
Расскажите пожалуйста, как "только врапперами, которые фильтруют" реализовать обработку исключений?
Мне кажется вы не поняли на каком этапе происходит подмена. Это не в риалтайме. А когда загружается код внешнего апплета, именно в этот момент все конструкции, которые могут вызвать выполнение или загрузку сотороннего кода заменяются в коде на наши функции(которые уже будут фильтровать входящие параметры, которые могут генерироваться динамически).
Речь идет о том, что в риалтайме потребуется анализировать каждый чих. Та самая фильтрация - что разрешать, а что запрещать.

Отсюда огромный объем работы - а не "прстая" фильтрация слов window и document.
Only those users with full accounts are able to leave comments. Log in, please.

Articles