Предполагалось, что я хотел бы воспользоваться способностью Common Lisp читать и выполнять Common Lisp-код, чтобы моя программа могла выполнять внешний код, написанный в Lisp, но я не верю этому коду, поэтому я не хочу, чтобы он имел доступ к полная сила Common Lisp. Могу ли я ограничить его среду, чтобы он мог видеть только пакеты/символы, к которым я явно даю ему доступ, эффективно создавая DSL?Могу ли я выполнить ненадежный Common Lisp-код в ограниченной среде?
ответ
Чтобы прочитать код, начните с отключения *read-eval*
(что останавливает людей инъекционные выполнение во время синтаксического анализа, используя что-то вроде #.(do-evil-stuff)
. Вы, вероятно, хотите, чтобы сделать чтение с использованием пользовательских чтения таблицы, которая отключает большинство (если не все) Read- макросы. Вероятно, вы захотите сделать чтение с помощью пользовательского одноразового пакета, импортирующего только те символы, которые вы разрешаете.
После того, как вы прочитали предоставленный пользователем код, вам все равно нужно проверить, что нет неожиданной функции/macro в коде. Если вы использовали пользовательский пакет, вы должны иметь возможность подтвердить, что каждый символ попадает в любой из двух классов: «принадлежит к индивидуальному одноразовому пакету» (это материал, предоставленный пользователем) или «явно разрешено из других мест» (вы бы d этот список для создания пользовательского пакета).
Как только это будет сделано, вы сможете оценить его.
Однако, делать это правильно, было бы довольно осторожно, и вам действительно нужно, чтобы кто-то еще посмотрел на код и активно пытался вырваться из песочницы.
Взгляните на раздел «Безопасность читателя» в chapter 4 of Let over lambda, который обсуждает эту тему на некоторой глубине. В частности, вы, вероятно, хотите установить *read-eval*
в nil
. Чтобы решить ваш вопрос относительно ограничения доступа к среде, в Common Lisp это обычно сложно, так как он предназначен для обеспечения доступа к большинству компонентов системы в первую очередь. Возможно, вы можете использовать сложные идеи Let over lambda в направлении белых листинговых символов (по сравнению с черным списком макросимволов в связанной главе). Я не думаю, что есть готовые решения.