Предотвращение импорта Python-кода определенным модулям? - PullRequest
15 голосов
/ 29 августа 2009

Я пишу приложение, в котором пользователи могут ввести скрипт Python и выполнить его в песочнице. Мне нужен способ запретить импорту исполняемого кода определенных модулей, чтобы вредоносный код не был такой большой проблемой. Есть ли способ сделать это в Python?

Ответы [ 6 ]

22 голосов
/ 29 августа 2009

Если вы введете None в sys.modules для имени модуля, оно не будет импортировано ...

>>> import sys
>>> import os
>>> del os
>>> sys.modules['os']=None
>>> import os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named os
>>>
16 голосов
/ 29 августа 2009

Проверяли ли вы статью python.org на SandboxedPython и связанную статью ?

Обе эти страницы имеют ссылки на другие ресурсы.

В частности, PyPi RestrictedPython позволяет вам точно определить, что доступно, и имеет несколько «безопасных» значений по умолчанию.

7 голосов
/ 29 августа 2009

Google App Engine с открытым исходным кодом SDK содержит детальную и основательную реализацию механизмов, позволяющих остановить импорт нежелательных модулей (чтобы помочь обнаружить код, пытающийся импортировать модули, которые недоступны в производственных экземплярах App Engine), хотя даже это может быть подорвано, если пользовательский код был злым, а не просто ошибочным (производственные экземпляры, очевидно, имеют больше уровней защиты, например просто не имеют этих модулей вообще; -).

Так что все зависит от того, насколько глубокой должна быть ваша защита. В одном крайнем случае вы просто прячете встроенный __import__ в другое место и заменяете его своей функцией, которая выполняет все необходимые проверки перед делегированием на __builtin__; это может быть 20 строк кода, 30 минут на реализацию и тщательное тестирование ... но это может не надолго защитить вас, если кто-то достоверно предложит me миллион долларов, чтобы взломать вашу систему (и, гипотетически, я Конечно, я не был парнем, который был на самом деле добрым парнем ;-). С другой стороны, вы развертываете всестороннюю серию уровней защиты, которые могут занять тысячи строк и недель работы по внедрению и тестированию - учитывая такой бюджет ресурсов, я наверняка смог бы реализовать что-то, что I было бы не в состоянии проникнуть (но всегда есть риск, что кто-то ЕЩЕ РАЗ умнее и, конечно, лучше меня разбирается в Python!).

Итак, как глубоко вы хотите зайти, или, точнее, насколько глубоко вы можете зайти ...?

5 голосов
/ 17 декабря 2017

8 лет, да, а никто этого не понял? : /

Вы можете переопределить оператор import или функцию __import__.

Это всего лишь проверенный код писанины, потому что я не смог найти никакой законной ссылки:

import importlib

def secure_importer(name, globals=None, locals=None, fromlist=(), level=0):

    if name != 'C': print(name, fromlist, level)

    # not exactly a good verification layer
    frommodule = globals['__name__'] if globals else None
    if name == 'B' and frommodule != 'C':
        raise ImportError("module '%s' is restricted."%name)

    return importlib.__import__(name, globals, locals, fromlist, level)

__builtins__.__dict__['__import__'] = secure_importer

import C

и вот тесты для этого кода:

Python 3.4.3 |Anaconda 2.3.0 (32-bit)| (default, Mar  6 2015, 12:08:17) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>> 
B ('f',) 0
imported secure module
>>> from B import f
B ('f',) 0
linecache None 0
encodings.utf_8 ['*'] 0
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    from B import f
  File "\home\tcll\Projects\python\test\restricted imports\main.py", line 11, in secure_importer
    raise ImportError("module '%s' is restricted."%name)
ImportError: module 'B' is restricted.
>>> import C
>>> 

Пожалуйста, не комментируйте меня, используя Python34, у меня есть свои причины, и это мой основной интерпретатор Linux специально для тестирования вещей (например, кода выше) для моего основного проекта.

1 голос
/ 29 августа 2009

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

Я действительно не знаю специфики реализации песочницы в Python, но я думаю, что это то, что нужно сделать на уровне интерпретатора, и это далеко не просто!

0 голосов
/ 29 августа 2009

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

...