Python - Создание "скриптовой" системы - PullRequest
8 голосов
/ 15 октября 2010

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

программа будет редактором карт для игрового движка на основе плиток

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

Я хочу, чтобы система работала так.

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

У меня все хорошо, пока все очень просто.получить сценарий из текстового поля в виде строки, скомпилировать его в объект cod с помощью встроенной функции compile (), затем выполнить сценарий с exec statment

script = textbox.text #bla bla store the string
code = compile(script, "script", "exec") #make the code object
eval(code, globals())

дело в том, что я хочу убедиться,что эта функция не может вызвать никаких ошибок или ошибок
скажем, если в скрипте есть оператор импорта.это вызовет какие-либо проблемы, принимая во внимание, что код был скомпилирован с чем-то вроде py2exe или py2app?
как мне убедиться, что пользователь не может сломать критическую часть программы, такую ​​как изменение части GUI, при этом все еще позволяяих изменить данные проекта (данные хранятся в глобальных свойствах в своем собственном модуле)?Я думаю, что это будет означать изменение глобального dict, который передается в функцию eval.
как мне убедиться, что этот eval не может вызвать зависание программы из-за длинного или бесконечного цикла?как мне убедиться, что ошибка, возникшая внутри кода пользователя, не может привести к сбою всего приложения?

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

РЕДАКТИРОВАТЬ: Относительно ответов

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

на самом деле мне все равно, если они это делают.Я больше беспокоюсь о том, чтобы кто-то случайно не сломал то, о чем они не знали.если кто-то действительно хотел, они могли бы разорвать приложение на куски с помощью скриптовых функций, но мне было все равно.это будет их экземпляр, и все проблемы, которые они создают, исчезнут, когда они перезапустят приложение, если они не испортили файлы на HD.Я хочу предотвратить проблемы, которые возникают, когда пользователь дозирует что-то глупое.
такие вещи, как IOError's, SystaxErrors, InfiniteLoopErrors и т. Д.

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

и , если пользователи используют оператор import module для загрузки модуля даже из библиотеки по умолчанию, которая не являетсяиспользуется в остальной части класса.Может ли это вызвать проблемы с зависанием приложения Py2exe, Py2app или Freeze?что если они называют модальную сторону стандартной библиотеки?Достаточно ли того, чтобы модал присутствовал в том же каталоге, что и замороженный исполняемый файл?

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

Ответы [ 4 ]

5 голосов
/ 15 октября 2010

Простой ответ: нет.

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

Тем не менее, я сделал это для веб-приложений, которые выполняют ввод данных пользователем, и да, вызовите eval следующим образом:

eval(code, {"__builtins__":None}, {safe_functions})

где safe_functions - это словарь, содержащий пары функций типа {"name": func}, к которым ваши пользователи должны иметь доступ.Если есть какая-то существенная структура данных, которую вы положительны , ваши пользователи никогда не захотят ткнуть в нее, просто вытащите ее из globals, прежде чем вводить их.

Кстати, Гвидо обратился к этомувопрос в своем блоге некоторое время назад.Я посмотрю, смогу ли я найти его.

Редактировать: найдено.

1 голос
/ 15 октября 2010

Краткий ответ: Нет

Другие похожие посты:

Создать сеть безопасности нелегко. Детали слишком много и умные взломы вокруг:

О ваших целях дизайна:

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

Самый простой вариант - попросить их написать скрипт, который вы сможете оценить (оценить) во время работы программы.

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

0 голосов
/ 15 октября 2010

Если у вас есть возможность переключиться на Tkinter, вы можете использовать встроенный интерпретатор tcl для обработки вашего скрипта. В этом отношении вы, вероятно, можете сделать это с помощью приложения wxpython, если не запускаете цикл событий tk; просто используйте интерпретатор tcl, не создавая никаких окон.

Поскольку интерпретатор tcl - это отдельная вещь, сбить интерпретатор python практически невозможно, если вы внимательно следите за тем, какие команды вы предоставляете tcl. Кроме того, tcl делает создание DSL очень простым.

Python - единственный язык сценариев со встроенным механизмом сценариев: -).

0 голосов
/ 15 октября 2010

Я бы посоветовал предоставить какой-нибудь API подключаемых модулей и позволить пользователям предоставлять подключаемые модули в виде текстовых файлов. Затем вы можете импортировать их как модули в свое собственное пространство имен, улавливая синтаксические ошибки в процессе, и вызывать различные функции, определенные в подключаемом модуле, снова проверяя наличие ошибок. Вы можете предоставить модуль API, который определяет функции / классы из вашей программы, к которым имеет доступ подключаемый модуль. Это дает вам свободу вносить изменения в архитектуру вашего приложения, не нарушая плагинов, поскольку вы можете просто адаптировать модуль API для предоставления функциональности таким же образом.

...