Как безопасно позволить пользователям запускать произвольный код Ruby? - PullRequest
8 голосов
/ 04 апреля 2010

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

Я пытаюсь предотвратить что-то вроде этого:

system("rm -rf /")
eval("something_evil")
# etc...

Я уверен, что должен быть какой-то достаточно безопасный способ сделать это, так как он уже существует в таких местах, как tryruby.org. Любая помощь с благодарностью, спасибо!

Ответы [ 4 ]

6 голосов
/ 04 апреля 2010

Три предложения:

1) Взгляните на Ruby уровни загрязнения .Это обеспечивает некоторую степень защиты от вещей типа eval('evil_code') и т. Д.

2) Если пользователю фактически не нужен доступ к локальной файловой системе, используйте что-то вроде fakefs

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

3 голосов
/ 04 апреля 2010

Запустите программу с указанным в белом списке разрешенных системных вызовов, как пользователь / группа никто, с ограничениями ресурсов (использование памяти и т. Д.) В минимальном режиме.

2 голосов
/ 04 апреля 2010

«Чистый лист» - это объект, лишенный (большей части) своих методов. «Чистая комната» - это объект, внутри которого вы оцениваете потенциально небезопасную комнату. Если вы оцениваете код в «чистой комнате», которая также является «чистым листом», поднимая уровень безопасности до самого высокого уровня, вы обеспечите себе большую защиту. Ничто в безопасности не может быть уверенным, поэтому этот уровень безопасности следует рассматривать как слой, не обязательно слой only .

Этот ответ показывает, как это сделать .

0 голосов
/ 08 декабря 2013

У меня была такая же проблема, но потом я наткнулся на eval.so и решил написать для нее оболочку API, которая называется Sandie . Это так же просто, как:

sandie = Sandie.new(language: 'ruby')
# => #<Sandie:0x00000002e30650>
sandie.evaluate(code: 'puts "hello world"')
# => {"stdout"=>"hello world\n", "stderr"=>"", "wallTime"=>487, "exitCode"=>0}

Он также поддерживает множество других языков, таких как C #, Perl, Lua и Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...