LuaSandbox/ru
LuaSandbox is an extension for PHP 7 and PHP 8 to allow safely running untrusted Lua 5.1 code from within PHP, which will generally be faster than shelling out to a Lua binary and using inter-process communication.
Установка
Распаковка
LuaSandbox доступен в Debian 10 и Ubuntu 18.04 и позже. Установка с помощью следующей команды:
apt install php-luasandbox -y
PECL
LuaSandbox теперь доступен в PECL, который также предоставляет предварительно созданные DLL для Windows. См. ссылки на страницы распакованного пакета. Сначала получите правильную библиотеку Lua 5.1, как описано ниже в разделе "ручная установка". Потом запускать :
pecl install luasandbox
Установка
Требования
Установите заголовки и файлы библиотеки для PHP и Lua 5.1.
- Для дистрибутивов Linux, полученных из Debian, таких как Ubuntu:
apt install php-dev liblua5.1-0-dev -y
- Для дистрибутивов Linux, полученных из CentOS/Redhat:
yum install php-devel lua5.1 lua5.1-devel
- Для macOS
brew install lua
Загрузка
Загрузить исходный код в соответствующий каталог из git:
git init
git pull https://gerrit.wikimedia.org/r/mediawiki/php/luasandbox.git
Или загрузить снимок кода и распаковать.
Сборка
luasandbox
- это каталог, в который был клонирован\скопирован репозиторий LuaSandbox Git.
cd luasandbox
phpize && ./configure && make && sudo make install
Затем добавьте extension=luasandbox.so
в конфигурацию PHP в соответствующем месте.
Например, в современных дистрибутивах, полученных от Debian, вы добавляете файл в /etc/php/$version/mods-available
(где $version
- версия PHP, для которой вы выполняли LuaSandbox) и используете команду phpenmod
для включения.
Если вы используете LuaSandbox с веб-приложением, таким как MediaWiki, вам нужно будет перезагрузить веб-сервер или php-fpm
для PHP для загрузки расширения.
(выполнить команду php update.php)
После такой перезагрузки вы должны увидеть LuaSandbox в выходе phpinfo()
и get_loaded_extensions()
(и, для MediaWiki с установленным Scribunto, Special:Version).
Примеры
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 50 * 1024 * 1024 );
$sandbox->setCPULimit( 10 );
// Зарегистрировать \ (записать) некоторые функции в среде Lua
function frobnosticate( $v ) {
return [ $v + 42 ];
}
$sandbox->registerLibrary( 'php', [
'frobnosticate' => 'frobnosticate',
'output' => function ( $string ) {
echo "$string\n";
},
'error' => function () {
throw new LuaSandboxRuntimeError( "Если не получается" );
}
] );
// Использовать некоторый код Lua, включая обратные вызовы в PHP и в Lua
$luaCode = <<<EOF
php.output( "Hello, world" );
return "Hi", function ( v )
return php.frobnosticate( v + 200 )
end
EOF;
list( $hi, $frob ) = $sandbox->loadString( $luaCode )->call();
assert( $frob->call( 4000 ) === [ 4242 ] );
// PHP-брошенный (старый код) LuaSandboxRuntimeError исключения могут быть запечатлены внутри Lua
list( $ok, $message ) = $sandbox->loadString( 'return pcall( php.error )' )->call();
assert( !$ok );
assert( $message === 'Something is wrong' );
Документация
Наша документация теперь находится в руководстве PHP в https://www.php.net/book.luasandbox.
Если вы хотите изменить руководство, вы можете либо отправить запрос на снятие с PHP руководство хранилище в GitHub, либо изменить наше зеркало главы LuaSandbox в проекте Gerrit расширения.
Отличия от стандартного Lua
LuaSandbox обеспечивает среду с песочницами, которая в некоторых отношениях отличается от стандартной Lua 5.1.
Не доступны следующие функции и пакеты:
dofile()
,loadfile()
, иio
пакет, так как они позволяют прямой доступ к файловой системе. При необходимости доступ к файловой системе должен быть осуществлен с помощью обратных вызовов PHP.- Пакет
package
включаяrequire()
иmodule()
, так как он сильно зависит от прямого доступа к файловой системе. Вместо этого может быть использована перезапись на чистом Lua, такая как , которая используется в Scribunto. load()
иloadstring()
, чтобы позволить статический анализ (проверку) кода Луи.print()
, так как он выходит на стандартный выход. При необходимости выход должен быть выполнен с помощью PHP-возобновлений (возврата).- Большинство пакетов
os
, так как позволяет манипулировать процессом и выполнять другие процессы.os.clock()
,os.date()
,os.difftime()
, andos.time()
остаются доступными.
- Большинство пакета
debug
позволяет изменять состояние Луи и метаданными таким образом, что может сломать страницу в песочнице.debug.traceback()
остается доступным.
string.dump()
, так как это может раскрыть внутренние данные.- Пакет
collectgarbage()
,gcinfo()
, иcoroutine
не были проверены в целях безопасности.
Внесены изменения в следующие характеристики:
pcall()
иxpcall()
не могут обнаружить определенные ошибки, особенно ошибки в сроках отсрочки.tostring()
не включает адреса указателей.string.match()
был отредактирован для ограничения глубины рекурсии и периодического проверки задержки времени.math.random()
иmath.randomseed()
заменяются версиями, которые не разделяют состояние сrand()
PHP.- Методы Lua 5.2
__pairs
и__ipairs
поддерживаютсяpairs()
иipairs()
.
История
За годы работы язык шаблона викитекста MediaWiki приобрел больше функций и стал более сложным. Еще в 2009 году разработчики MediaWiki начали обсуждать идею внедрения реального языка скрипта вместо того, чтобы продолжать делать викитекст более сложным.
Требования к такому проекту включали сильную песчаную ящик и строгие ограничения на использование памяти и времени процессора, поскольку это было бы выполнение ненадежного пользовательского кода на производственных серверах. Он должен быть использователен, используя самостоятельный бинарный файл, и возможность запуска в процессе через расширение PHP для улучшения производительности является основным преимуществом.
Когда развитие началось всерьез около 2011 года, были выявлены четыре языка-кандидаты: Lua, JavaScript, PHP или гипотетический язык "WikiScript", который должен быть разработан. У $1 имеется несколько недостатков.72% соответствия У Луа было несколько преимуществ:
- Маленький (170 тыс. скачиваний) и быстрый. Существование LuaJIT также считалось выгодой.
- Разработан для вкладки, включая легкие хуки для процессора и ограничения памяти.
- Простая песочница, нет внутренних конфликтов.
- Подробная справочная книга, включающая инструкции по встроению.
Основным недостатком было то, что он не был известен так широко, как JavaScript.
JavaScript, в виде двигателя V8 в то время, имел несколько недостатков:
- Минимальная документация о внедрении.
- Продолжается поддержка внедрения длительно.
- Нет никакого раздела.
- Огромный самостоятельный бинар.
Движок Rhino был хуже, так как был написан на Яве, он не мог быть встроен в PHP. Сам PHP был отклонен, поскольку правильное внедрение и sandboxing были бы чрезвычайно сложными, а предварительный просмотр был бы медленным, а "Викискрипт" был бы гораздо более крупным проектом, посколькам потребовал бы разработки переводчика (или двух) с нуля.
Таким образом, была выбрана Lua, в частности версия 5.1 , которая была доступна в то время, и это расширение PHP было разработано. Изменения, внесенные в управлении функциональной средой в 5.2 препятствовали простому обновлению, с тех пор см. подробности в phab:T178146 .