2012-04-30 2 views
3

У меня есть два на вопросы, касающиеся Pysandbox:Pysandbox вопросы конфигурации

  1. Как достичь функциональности eval? Я понимаю, что sandbox.execute() эквивалентен exec, но я не могу найти ничего такого, что если бы введенный код был 2 + 2, тогда он вернул 4 или что-то в этом роде.

  2. По умолчанию sandbox.execute() делает переданную среду доступной только для чтения - то есть если я делаю sandbox.execute('data.append(4)', locals={'data': [1, 2, 3]}), произойдет ошибка. Как создать среду с передачей в режиме чтения-записи?

+0

Мы смотрим на тот же Pysandbox - тот, который находится на https://github.com/haypo/pysandbox?Ваш второй пример, кажется, работает без ошибок для меня, и первый выглядит так, как будто он просит sandbox.call (lambda: 2 + 2). –

+0

Да, это тот же модуль. Во втором примере была сделана ошибка в том, что объект доступен только для чтения. Что касается eval, я хочу функцию, которая автоматически пытается eval, так что мне не нужно будет анализировать входные данные, чтобы определить, является ли это кодом, гарантирующим eval vs. exec. – Zach

+0

Возможно, существует разница в том, как вы настраиваете свою изолированную программную среду , Не могли бы вы опубликовать весь сценарий и ошибку, возникающую при попытке обновления? –

ответ

1

Ага, я вижу, что релиз последней PySandbox (1,5) не ведут себя, как вы описываете. Я пытался на ветку гит-мастера.

Для вопроса 1, я не думаю, что есть прямые варианты с PySandbox 1.5. Код был написан специально, чтобы попытаться запретить модификацию или передачу какого-либо состояния во встроенной песочнице. sandbox.call(eval, CODE) не является хорошим вариантом, так как вы не можете легко пройти в пространствах имен локалей и глобалов (вы можете попробовать, но песочница будет проксировать их, а затем eval() будет терпеть неудачу, потому что locals и globals должны быть реальными dicts) , И я считаю, что вы хотите, чтобы здесь были установлены местные жители и глобальные сообщества.

Вопрос 2 не является простым, по тем же причинам. Обе эти возможности возможны в текущей ветке git master, но неясно, связано ли это с ошибками или по дизайну :)

Итак, вот решение обоих вопросов, которое расширяет функциональность песочницы и использует то, что, вероятно, означает быть частным интерфейсом, но по-прежнему должны быть безопасными, как песочница иначе:

from sandbox.proxy import proxy 
from sandbox.sandbox_class import _call_exec 

def proxyNamespace(d): 
    return dict((str(k), proxy(v)) for k, v in d.iteritems()) 

def wrapeval(codestr, globs, locs): 
    subglobs = proxyNamespace(globs) 
    sublocs = proxyNamespace(locs) 
    return eval(codestr, subglobs, sublocs) 

def eval_in_sandbox(sandbox, codestr, globs=None, locs=None): 
    if globs is None: 
     globs = {} 
    if locs is None: 
     locs = globs 
    return sandbox._call(wrapeval, (codestr, locs, globs), {}) 

def exec_in_sandbox_with_mutable_namespace(sandbox, codestr, globs=None, locs=None): 
    if globs is None: 
     globs = {} 
    if locs is None: 
     locs = globs 
    subglobs = proxyNamespace(globs) 
    sublocs = proxyNamespace(locs) 
    sandbox._call(_call_exec, (codestr, subglobs, sublocs), {}) 
    globs.update(subglobs) 
    locs.update(sublocs) 

Теперь все, что сказал, я настоятельно рекомендую не базировать безопасность любого фактического кода производства или системы на этом PySandbox модуль. Просматривая код, кажется, что он полностью пронизан недостатками и дырками. Я не думаю, что для того, чтобы найти пути мимо такого рода безопасности, понадобится атакующему больше часа или около того. Я также не думаю, что это подверглось серьезному анализу со стороны специалистов по безопасности или даже очень большой части сообщества в целом. Если вы хотите запустить ненадежный код и не сможете вообще повлиять на ваш процесс, вам нужно что-то большее, возможно, основанное на AppArmor или что-то в этом роде. Если вас беспокоит только случайный неправильный код, а не вредоносный, это может быть хорошо, но я на самом деле даже не уверен в этом.

+0

Я признаю, что PySandbox не может быть серьезным способом. Но ваш путь очень вводит в заблуждение. – wuliang

+0

Sandbox._call не будет использоваться для выполнения какого-либо кода, если вы не хотите быть «жертвой». Я буду называть sandbox.execute для запуска любого ненадежного кода. Можете привести пример? – wuliang

+0

@wuliang Я не уверен, что вы имеете в виду. Что вводит в заблуждение? И какой вам пример? –

0

Вопрос 1:

sandbox.call(eval, "2+2") 

Вопрос 2:

from sandbox import Sandbox, SandboxConfig 
cfg=SandboxConfig('stdout') 
import sys 

out1 = sys.stdout 
err1 = sys.stderr 
with open("logfile.txt", "w") as f:  
    sys.stdout = sys.stderr = f 
    sandbox = Sandbox(cfg) 
    indata={'data': [1, 2, 3]} 
    sandbox.execute('a=list(data);a.append(4); print(str(a))', locals=indata) 

sys.stdout = out1 
sys.stderr = err1 

with open("logfile.txt", "r") as f: 
    indata=eval(f.read()) 
    print indata 

Некоторые замечание о вопросе 2, Это трудно получить читаемую-Writebale объект и сделать его видно снаружи на в то же время. Я бы хотел увидеть более умные методы.

ВЫВОД:

$ python test.py 
[1, 2, 3, 4] 
+0

Было бы бесполезно запускать код в песочнице, а затем идти вперед и eval() независимо от того, что песочница была напечатана на stdout. –

+0

К сожалению, я все равно хотел бы написать изменения в среду для 1). Для 2) я не уверен, как этот метод будет работать для объектов более сложных, чем базовые структуры данных и литералы. А именно, если я создал функцию, которую я хотел сохранить в среде, я не совсем уверен, как это сделать с помощью этого метода. – Zach

+0

@ Zach, я думаю, что нет общего способа сделать это. Что такое «песочница», это сделать ваш код запущенным в своем виртуальном ящике. Даже мы можем найти какой-то трюк, чтобы заставить его работать, это хакерский метод и будет отключен, если «песочница» будет обновлена ​​до патч-дыры. – wuliang

Смежные вопросы