Есть ли способ заключить в тюрьму в JavaScript, так, чтобы DOM не был видим

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

Пример: Если интерфейс checkanswer(func) это позволяется:

checkanswer( function (x,y)={
   return x+y;
}

но они не позволяются:
alert(1)
document.write("hello world")
eval("alert()")

Править: то, что я имел в виду, было простым языком, который был реализован с помощью JavaScript, чего-то как http://stevehanov.ca/blog/index.php?id=92

9
задан TiansHUo 20 April 2010 в 08:49
поделиться

6 ответов

( Edit Этот ответ относится к вашему вопросу перед редактированием. Не знаю ни одного скриптового языка, реализованного с использованием Javascript, хотя я полагаю, что они есть. Например, однажды кто-то написал BASIC для Javascript (раньше была ссылка, но она сгнила). Поэтому оставшаяся часть этого ответа довольно академична, но я оставил ее только для обсуждения, иллюстрации и даже в целях предупреждения. Кроме того, я определенно согласен с bobince's очков - не делайте этого самостоятельно, используйте работу других, например Caja .)

Если вы разрешаете использование сценариев в пользовательском контенте, будьте готовы к тому, что вы » Вы будете участвовать в гонке вооружений, когда люди будут находить бреши в ваших механизмах защиты и эксплуатировать их, а вы отвечаете на эти подвиги. Думаю, я бы, наверное, уклонился от этого, но вы знаете свое сообщество и свои варианты борьбы с насилием. Итак, если вы готовы к этому:

Из-за того, как Javascript выполняет разрешение символов, кажется, что должна быть возможность оценить сценарий в контексте, где window , document , ActiveXObject , XMLHttpRequest и подобные не имеют своего обычного значения:

// Define the scoper
var Scoper = (function() {
    var rv = {};

    rv.scope = function(codeString) {
        var window,
            document,
            ActiveXObject,
            XMLHttpRequest,
            alert,
            setTimeout,
            setInterval,
            clearTimeout,
            clearInterval,
            Function,
            arguments;
            // etc., etc., etc.

        // Just declaring `arguments` doesn't work (which makes
        // sense, actually), but overwriting it does
        arguments = undefined;

        // Execute the code; still probably pretty unsafe!
        eval(codeString);
    };

    return rv;;
})();

// Usage:
Scoper.scope(codeString);

(Теперь, когда используется злой eval , но я могу » Сразу придумайте способ скрыть объекты по умолчанию в кросс-браузере без использования eval , и если вы все равно получаете код в виде текста ...)

Но это не работа , это лишь частичное решение (подробнее ниже).Логика заключается в том, что любая попытка в коде в codeString получить доступ к окну (например) будет обращаться к локальной переменной window , а не к глобальной; и то же самое для остальных. К сожалению, из-за способа разрешения символов любое свойство окна может быть доступно с окном или без него. Префикс (например, alert ), поэтому вы должны указать и их. Это может быть длинный список, не в последнюю очередь потому, что, как указывает bobince , IE выгружает любой элемент DOM с именем или идентификатором в окно . Так что вам, вероятно, придется поместить все это в отдельный iframe, чтобы вы могли выполнить конечный прогон вокруг этой проблемы, и «только» придется иметь дело со стандартными вещами. Также обратите внимание, как я сделал функцию scope свойством объекта, а затем вы только вызываете ее через свойство. Это значит, что this устанавливается в экземпляр Scoper (в противном случае при вызове необработанной функции this по умолчанию имеет значение окно !).

Но, как отмечает Бобинс, существует очень много разных способов добиться желаемого. Например, этот код в codeString успешно разрушает тюрьму, указанную выше:

(new ('hello'.constructor.constructor)('alert("hello from global");'))()

Теперь, может быть , вы могли бы обновить тюрьму, чтобы этот конкретный эксплойт не работал (возиться с ] конструктор свойства для всех - всех - встроенных объектов), но я склонен в этом сомневаться.И если бы вы могли , кто-то (например, Боб) просто придумал бы новый эксплойт, вроде этого:

(function(){return this;})().alert("hello again from global!");

Отсюда «гонка вооружений».

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

14
ответ дан 4 December 2019 в 09:36
поделиться

Вы можете сделать это так же, как Facebook. Они предварительно обрабатывают все источники javascript, добавляя префикс ко всем именам, кроме их собственных API-интерфейсов оболочки.

0
ответ дан 4 December 2019 в 09:36
поделиться

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

Не пытайтесь брать это на себя. Рассмотрите возможность использования существующего проекта «mini-JS-подобного языка», такого как Caja .

3
ответ дан 4 December 2019 в 09:36
поделиться

T.J. Краудер отлично замечает «гонку вооружений». Будет очень сложно построить водонепроницаемую песочницу.

Однако можно довольно легко переопределить определенные функции.

Простые функции:

И согласно этот вопрос , даже переопределение таких вещей, как document.write так же просто, как

document.write = function(str) {}

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

Альтернативные варианты:

  • Помещение скрипта в песочницу в IFrame на другом субдомене. Можно было бы манипулировать собственным DOM и генерировать alert () и тому подобное, но окружающий сайт останется нетронутым. Возможно, вам все равно придется это сделать, независимо от того, какой метод (ы) вы выберете

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

  • Существует несколько методов отслеживания изменений в DOM, и я почти уверен, что можно создать механизм, который немедленно отменяет любые изменения, очень похожий на управление DLL в Windows. Но это будет ужасно сложно построить и очень ресурсоемко.

5
ответ дан 4 December 2019 в 09:36
поделиться

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

0
ответ дан 4 December 2019 в 09:36
поделиться

У меня есть другой способ: использовать Google Gears WorkerPool api
{{1} } См. Это
http://code.google.com/apis/gears/api_workerpool.html

Созданный рабочий не имеет доступа к DOM; такие объекты, как документ и окно, существуют только на главной странице. Это следствие того, что рабочие не разделяют какое-либо состояние выполнения. Однако рабочие имеют доступ ко всем встроенным функциям JavaScript. Также можно использовать большинство методов Gears через глобальную переменную, которая определяется автоматически: google.gears.factory. (Единственным исключением является средство отправки файлов LocalServer, которому требуется DOM.) Для других функций созданные рабочие процессы могут запрашивать главную страницу для выполнения запросов. .

0
ответ дан 4 December 2019 в 09:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: