Песочница на Python это сложно . Python по своей сути интроспективен на нескольких уровнях.
Это также означает, что вы можете найти фабричные методы для конкретных типов из самих этих типов и создать новые низкоуровневые объекты, которые будут выполняться интерпретатором напрямую без ограничений.
Вот несколько примеров поиска творческих способов вырваться из песочниц Python:
Нед Бэтчелдер начинает с демонстрации того, насколько опасен на eval()
самом деле ; eval()
часто используется для выполнения выражений Python; как примитивная и наивная песочница для однострочников.
Затем он продолжил пытаться применить те же принципы к Python 3 , в конечном итоге преуспев в достижении некоторых полезных указателей.
Пьер Бурдон использует аналогичные методы, чтобы взломать систему Python на взломать
Основная идея всегда состоит в том, чтобы найти способ создания базовых типов Python; функции и классы и вырваться из оболочки, заставив интерпретатор Python выполнить произвольный (непроверенный!) байт-код.
То же самое и более относится к exec
утверждению ( exec()
функция в Python 3).
Итак, вы хотите:
Строго контролируйте байтовую компиляцию кода Python или, по крайней мере, постобработайте байт-код, чтобы исключить любой доступ к именам, начинающимся с подчеркиваний.
Это требует глубоких знаний о том, как работает интерпретатор Python и как структурирован байт-код Python. Объекты кода являются вложенными; Байт-код модуля охватывает только верхний уровень операторов, каждая функция и класс состоят из собственной последовательности байт-кода плюс метаданные, содержащие, например, другие объекты байт-кода для вложенных функций и классов.
Вам необходимо внести в белый список модули, которые можно использовать. Осторожно.
Модуль Python содержит ссылки на другие модули. Если вы импортируете os
, os
в вашем пространстве имен модуля будет находиться локальное имя, которое относится к os
модулю. Это может привести решительного злоумышленника к модулям, которые могут помочь им вырваться из песочницы. pickle
Модуль, например, позволяет загружать произвольные объекты кода, например, так что если какой - либо путь через белый список модулей приводит к pickle
модулю, то есть проблема до сих пор.
Вам необходимо строго ограничить временные квоты. Даже самый стерилизованный код может работать вечно, связывая ваши ресурсы.
Взгляните на RestrictedPython , который пытается дать вам строгий контроль байт-кода. RestrictedPython
превращает код Python во что-то, что позволяет вам контролировать, какие имена, модули и объекты допустимы в Python с 2.3 по 2.7.
Если RestrictedPython
это достаточно безопасно для ваших целей, зависит от политики, которую вы реализуете. Запрет доступа к именам, начинающимся с подчеркивания и строго внесения в белый список модулей, будет началом.
По моему мнению, единственный действительно надежный вариант - это использовать отдельную виртуальную машину, которая не имеет доступа к сети во внешний мир, который вы уничтожаете после каждого запуска. Каждый новый скрипт получает новую виртуальную машину. Таким образом, даже если коду удастся вырваться из вашей изолированной программной среды Python (что не исключено), весь доступ к злоумышленнику будет кратковременным и бесполезным.