Песочница для выполнения возможно недружественного кода Python
Допустим, в Интернете есть сервер, на который можно отправить фрагмент кода для оценки. В какой-то момент сервер берет весь отправленный код и начинает его запуск и оценку. Однако, в какой-то момент он определенно натолкнется на "os.system('rm -rf *')", отправленный каким-то злым программистом. Помимо "rm -rf" вы можете ожидать, что люди попытаются использовать сервер для рассылки спама или рассылки кому-то, или же будут дурачиться с вещами "while True: pass".
Есть ли способ справиться с таким недружественным / ненадежным кодом? В частности, я заинтересован в решении для Python. Однако, если у вас есть информация для любого другого языка, пожалуйста, поделитесь.
7 ответов
Вы можете проверить pysandbox, который делает именно это, хотя маршрут VM, вероятно, безопаснее, если вы можете себе это позволить.
Если вы не относитесь конкретно к реализации CPython, вам следует рассмотреть возможность просмотра PyPy [wiki] для этих целей - этот диалект Python позволяет выполнять прозрачную песочницу кода.
В противном случае вы можете предоставить поддельные __builtin__
а также __builtins__
в соответствующих аргументах глобальных / локальных exec
или же eval
,
Более того, вы можете предоставить словарный объект вместо реального словаря и отследить, что ненадежный код делает с его пространством имен.
Более того, вы можете проследить этот код (выдача sys.settrace()
в ограниченной среде до выполнения любого другого кода), поэтому вы можете прервать выполнение, если что-то пойдет не так.
Если ни одно из решений не является приемлемым, используйте "песочницу" на уровне ОС, например chroot
, unionfs
и стандарт multiprocess
Модуль Python для порождения кода работника в отдельном защищенном процессе.
Невозможно дать абсолютное решение для этого, потому что определение "плохого" довольно сложно определить.
Открытие или запись в файл - это плохо или хорошо? Что если этот файл / dev / ram?
Вы можете профилировать сигнатуры поведения или пытаться заблокировать все, что может быть плохим, но вы никогда не выиграете. Javascript - довольно хороший пример того, что люди постоянно запускают произвольный код javascript на своих компьютерах - он должен быть изолированным, но возникают всевозможные проблемы безопасности и пограничные условия.
Я не говорю, не пытайтесь, вы многому научитесь из процесса.
Многие компании потратили миллионы (Intel только что потратила миллиарды на McAffee), пытаясь понять, как обнаружить "плохой код" - и каждый день компьютеры, на которых установлен антивирус McAffe, заражаются вирусами. Код Python не менее опасен, чем C. Вы можете запускать системные вызовы, связываться с библиотеками C и т. Д.
Я бы серьезно подумал о том, чтобы виртуализировать среду, чтобы запустить этот материал, так что эксплойты в любом механизме, который вы реализуете, могут быть еще раз заблокированы настройкой виртуальной машины.
Количество пользователей и тип кода, который вы ожидаете протестировать / запустить, окажут значительное влияние на выбор между прочим. Если от них не ожидается, что они будут ссылаться на файлы или базы данных или выполнять вычислительно-сложные задачи, и у вас будет очень низкое давление, у вас может получиться почти нормально, просто полностью запретив доступ к файлу и установив ограничение по времени для процесса, прежде чем он будет уничтожен и представление помечено как слишком дорогое или злонамеренное.
Если код, который вы должны тестировать, может быть произвольным расширением или страницей Django, то вам, вероятно, предстоит большая работа.
Я думаю, что такое исправление будет очень трудным, и оно напоминает мне лекцию, которую я посетил, о преимуществах программирования в виртуальной среде. Если ты делаешь это практически, это круто, если они убивают это. Это не решит некоторое время True: pass, но rm -rf / не будет иметь значения.
Если я не ошибаюсь (и я вполне могу ошибаться), это во многом является причиной того, как Google изменил Python для App Engine. Вы запускаете код Python на их сервере, но они удалили возможность записи в файлы. Все данные сохраняются в базе данных "nosql".
Это не прямой ответ на ваш вопрос, а пример того, как эта проблема решалась в некоторых обстоятельствах.