LuaSandbox: Difference between revisions
Justman10000 (talk | contribs) m Sudo unnecessary + Simply use apt instead of apt-get |
m restore translation units |
||
| (18 intermediate revisions by 12 users not shown) | |||
| Line 1: | Line 1: | ||
<languages /> |
<languages /> |
||
''<translate><!--T:1--> For the MediaWiki extension that allows use of sandboxed Lua code, see <tvar name=1>{{ll|Extension:Scribunto}}</tvar></translate>'' |
|||
<translate> |
<translate> |
||
<!--T:2--> |
<!--T:2--> |
||
| Line 7: | Line 8: | ||
== Installation == <!--T:3--> |
== Installation == <!--T:3--> |
||
=== |
=== Linux package manager === <!--T:4--> |
||
</translate> |
</translate> |
||
<translate><!--T:5--> LuaSandbox is available in |
<translate><!--T:5--> LuaSandbox is available on Linux in the [<tvar name=debian>https://packages.debian.org/stable/php-luasandbox</tvar> Debian] and [<tvar name=ubuntu>https://packages.ubuntu.com/search?keywords=php-luasandbox&searchon=names</tvar> Ubuntu] repositories.</translate> |
||
<translate><!--T:6--> Install with the following command:</translate> |
<translate><!--T:6--> Install with the following command:</translate> |
||
| Line 15: | Line 16: | ||
apt install php-luasandbox -y |
apt install php-luasandbox -y |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
<translate> |
|||
<!--T:87--> |
|||
LuaSandbox can be installed on RPM-based distributions (Fedora, RedHat, SUSE, etc.) using <code>yum</code> from [<tvar name=1>https://rpms.remirepo.net/</tvar> Remi's repository] ([<tvar name=url>https://rpmfind.net/linux/rpm2html/search.php?query=php-pecl-luasandbox</tvar> package list]).</translate> |
|||
=== PIE === |
|||
| ⚫ | |||
| ⚫ | |||
<code>pie install wikimedia/luasandbox</code> |
|||
See [https://packagist.org/packages/wikimedia/luasandbox LuaSandbox in Packagist]. |
|||
<translate> |
<translate> |
||
=== PECL === <!--T:7--> |
=== PECL === <!--T:7--> |
||
</translate> |
</translate> |
||
PECL is deprecated as of 2026. |
|||
<translate><!--T:8--> LuaSandbox is now available in PECL, which also provides pre-built Windows DLLs.</translate> |
|||
New releases will not be published to PECL. |
|||
<translate><!--T:9--> See [<tvar name=url>https://pecl.php.net/package/LuaSandbox</tvar> our package page].</translate> |
|||
| ⚫ | |||
To install LuaSandbox with PECL, first get the correct Lua 5.1 library, then run: |
|||
| ⚫ | |||
<pre> |
<pre> |
||
| Line 29: | Line 43: | ||
<translate> |
<translate> |
||
=== |
=== Build from source === <!--T:12--> |
||
<!--T:13--> |
|||
'''Requirements''': |
|||
<!--T:14--> |
<!--T:14--> |
||
Install the headers and library files for PHP and [<tvar name=url>https://www.lua.org/</tvar> Lua] 5.1. |
Install the headers and library files for PHP and [<tvar name=url>https://www.lua.org/</tvar> Lua] 5.1. |
||
</translate> |
</translate> |
||
* <translate><!--T:15--> For Debian-derived Linux distributions, such as Ubuntu:</translate> <syntaxhighlight lang="bash"> |
* <translate><!--T:15--> For Debian-derived Linux distributions, such as Ubuntu:</translate> <syntaxhighlight lang="bash">apt install php-dev liblua5.1-0-dev -y</syntaxhighlight> |
||
* <translate><!--T:16--> For CentOS/Redhat-derived Linux distributions:</translate> <syntaxhighlight lang="bash"> |
* <translate><!--T:16--> For CentOS/Redhat-derived Linux distributions:</translate> <syntaxhighlight lang="bash">yum install php-devel lua5.1 lua5.1-devel</syntaxhighlight> |
||
* <translate><!--T:17--> For macOS</translate> <syntaxhighlight lang="bash">brew install lua</syntaxhighlight> |
|||
<translate> |
<translate> |
||
==== Download ==== <!--T:18--> |
|||
<!--T:19--> |
<!--T:19--> |
||
Download the source code into an appropriate directory from git: |
Download the source code into an appropriate directory from git: |
||
| Line 55: | Line 66: | ||
<!--T:20--> |
<!--T:20--> |
||
Or {{<tvar name=1>DownloadGitMaster|base=mediawiki-php-|luasandbox</tvar>|download a snapshot}} and unpack. |
Or {{<tvar name=1>DownloadGitMaster|base=mediawiki-php-|luasandbox</tvar>|download a snapshot}} and unpack. |
||
==== Build ==== <!--T:21--> |
|||
<!--T:22--> |
<!--T:22--> |
||
<tvar name=1><code>luasandbox</code></tvar> |
<tvar name=1><code>luasandbox/</code></tvar> is the directory with the LuaSandbox source code. |
||
</translate> |
</translate> |
||
<syntaxhighlight lang="bash"> |
<syntaxhighlight lang="bash"> |
||
cd luasandbox |
cd luasandbox/ |
||
phpize && ./configure && make && sudo make install |
phpize && ./configure && make && sudo make install |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
<translate><!--T:23--> Then add <tvar name=1><code>extension=luasandbox |
<translate><!--T:23--> Then add <tvar name=1><code>extension = luasandbox</code></tvar> to the PHP configuration in an appropriate place.</translate> |
||
<translate><!--T:24--> For example, in modern Debian-derived distributions you would add a file to <tvar name=1><code>/etc/php/$version/mods-available</code></tvar> (where <tvar name=2><code>$version</code></tvar> is the version of PHP for which you complied LuaSandbox) and use the <tvar name=3><code>phpenmod</code></tvar> command to enable it.</translate> |
<translate><!--T:24--> For example, in modern Debian-derived distributions you would add a file to <tvar name=1><code>/etc/php/$version/mods-available</code></tvar> (where <tvar name=2><code>$version</code></tvar> is the version of PHP for which you complied LuaSandbox) and use the <tvar name=3><code>phpenmod</code></tvar> command to enable it.</translate> |
||
<translate><!--T:25--> If you are using LuaSandbox with a web application such as MediaWiki, you will need to restart your web server or <tvar name=1><code>php-fpm</code></tvar> for PHP to load the extension.</translate> |
<translate><!--T:25--> If you are using LuaSandbox with a web application such as MediaWiki, you will need to restart your web server or <tvar name=1><code>php-fpm</code></tvar> for PHP to load the extension.</translate> |
||
<translate><!--T:26--> After such reload, you should see LuaSandbox in the output of <tvar name=1> |
<translate><!--T:26--> After such reload, you should see LuaSandbox in the output of <tvar name=1>{{phpi|phpinfo()}}</tvar> and <tvar name=2>{{phpi|get_loaded_extensions()}}</tvar> (and, for MediaWiki with Scribunto installed, <tvar name=3>[[Special:Version]]</tvar>).</translate> |
||
<translate> |
<translate> |
||
== Examples == <!--T:27--> |
== Examples == <!--T:27--> |
||
</translate> |
</translate> |
||
| Line 159: | Line 167: | ||
<translate> |
<translate> |
||
== History == <!--T:57--> |
== History == <!--T:57--> |
||
</translate> |
</translate> |
||
| Line 200: | Line 207: | ||
* [[File:Gerrit icon.svg|28px|link=Special:MyLanguage/Gerrit]] [[git:mediawiki/php/luasandbox|Gerrit <translate><!--T:80--> source code</translate>]] |
* [[File:Gerrit icon.svg|28px|link=Special:MyLanguage/Gerrit]] [[git:mediawiki/php/luasandbox|Gerrit <translate><!--T:80--> source code</translate>]] |
||
** [[File:Wikimedia Phabricator logo.svg|28px|link=Special:MyLanguage/Phabricator]] [[phab:diffusion/MLUS/repository/master/|Phabricator <translate><!--T:83--> mirror</translate>]] |
** [[File:Wikimedia Phabricator logo.svg|28px|link=Special:MyLanguage/Phabricator]] [[phab:diffusion/MLUS/repository/master/|Phabricator <translate><!--T:83--> mirror</translate>]] |
||
** [[File:Octicons-mark-github.svg|28px|link=Special:MyLanguage/Gerrit/GitHub]] [https://github.com/wikimedia/mediawiki-php-luasandbox GitHub <translate><!--T:84--> mirror</translate>] |
** [[File:Octicons-mark-github.svg|28px|link=Special:MyLanguage/Gerrit/GitHub|class=skin-invert-image]] [https://github.com/wikimedia/mediawiki-php-luasandbox GitHub <translate><!--T:84--> mirror</translate>] |
||
* [https://packages.debian.org/stable/php-luasandbox <translate><!--T:81--> Debian package</translate>] |
* [https://packages.debian.org/stable/php-luasandbox <translate><!--T:81--> Debian package</translate>] |
||
* [https://doc.wikimedia.org/mediawiki-php-luasandbox/master/annotated.html <translate><!--T:82--> Code documentation</translate>] |
* [https://doc.wikimedia.org/mediawiki-php-luasandbox/master/annotated.html <translate><!--T:82--> Code documentation</translate>] |
||
[[Category:PHP extensions{{#translation:}}]] |
[[Category:PHP extensions{{#translation:}}]] |
||
Latest revision as of 11:19, 30 July 2026
For the MediaWiki extension that allows use of sandboxed Lua code, see Extension:Scribunto
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.
Installation
[edit | edit source]Linux package manager
[edit | edit source]LuaSandbox is available on Linux in the Debian and Ubuntu repositories. Install with the following command:
apt install php-luasandbox -y
LuaSandbox can be installed on RPM-based distributions (Fedora, RedHat, SUSE, etc.) using yum from Remi's repository (package list).
PIE
[edit | edit source]To install LuaSandbox with PIE, first get the correct Lua 5.1 library as described below under "build from source". Then run:
pie install wikimedia/luasandbox
PECL
[edit | edit source]PECL is deprecated as of 2026. New releases will not be published to PECL.
To install LuaSandbox with PECL, first get the correct Lua 5.1 library, then run:
pecl install luasandbox
Build from source
[edit | edit source]Requirements:
Install the headers and library files for PHP and Lua 5.1.
- For Debian-derived Linux distributions, such as Ubuntu:
apt install php-dev liblua5.1-0-dev -y
- For CentOS/Redhat-derived Linux distributions:
yum install php-devel lua5.1 lua5.1-devel
Download the source code into an appropriate directory from git:
git clone https://gerrit.wikimedia.org/r/mediawiki/php/luasandbox.git
Or download a snapshot and unpack.
luasandbox/ is the directory with the LuaSandbox source code.
cd luasandbox/
phpize && ./configure && make && sudo make install
Then add extension = luasandbox to the PHP configuration in an appropriate place.
For example, in modern Debian-derived distributions you would add a file to /etc/php/$version/mods-available (where $version is the version of PHP for which you complied LuaSandbox) and use the phpenmod command to enable it.
If you are using LuaSandbox with a web application such as MediaWiki, you will need to restart your web server or php-fpm for PHP to load the extension.
After such reload, you should see LuaSandbox in the output of phpinfo() and get_loaded_extensions() (and, for MediaWiki with Scribunto installed, Special:Version).
Examples
[edit | edit source]$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 50 * 1024 * 1024 );
$sandbox->setCPULimit( 10 );
// Register some functions in the Lua environment
function frobnosticate( $v ) {
return [ $v + 42 ];
}
$sandbox->registerLibrary( 'php', [
'frobnosticate' => 'frobnosticate',
'output' => function ( $string ) {
echo "$string\n";
},
'error' => function () {
throw new LuaSandboxRuntimeError( "Something is wrong" );
}
] );
// Execute some Lua code, including callbacks into PHP and into 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-thrown LuaSandboxRuntimeError exceptions can be caught inside Lua
list( $ok, $message ) = $sandbox->loadString( 'return pcall( php.error )' )->call();
assert( !$ok );
assert( $message === 'Something is wrong' );
Documentation
[edit | edit source]Our documentation now lives within the upstream PHP manual at https://www.php.net/book.luasandbox.
If you want to change the manual, you can either submit a pull request against the PHP manual repository in GitHub, or change our mirror of the LuaSandbox chapter in the extension's Gerrit project.
Differences from standard Lua
[edit | edit source]LuaSandbox provides a sandboxed environment which differs in some ways from standard Lua 5.1.
The following functions and packages are not available:
dofile(),loadfile(), and theiopackage, as they allow direct filesystem access. If needed, filesystem access should be done via PHP callbacks.- The
packagepackage, includingrequire()andmodule(), as it depends heavily on direct filesystem access. A pure-Lua rewrite such as that used in Scribunto may be used instead. load()andloadstring(), to allow for static analysis of Lua code.print(), since it outputs to standard output. If needed, output should be done via PHP callbacks.- Most of the
ospackage, as it allows manipulation of the process and executing of other processes.os.clock(),os.date(),os.difftime(), andos.time()remain available.
- Most of the
debugpackage, as it allows manipulation of Lua state and metadata in ways that can break sandboxing.debug.traceback()remains available.
string.dump(), as it may expose internal data.collectgarbage(),gcinfo(), and thecoroutinepackage have not been reviewed for security.
The following features have been modified:
pcall()andxpcall()cannot catch certain errors, particularly timeout errors.tostring()does not include pointer addresses.string.match()has been patched to limit the recursion depth and to periodically check for a timeout.math.random()andmath.randomseed()are replaced with versions that don't share state with PHP'srand().- The Lua 5.2
__pairsand__ipairsmetamethods are supported bypairs()andipairs().
History
[edit | edit source]Over the years, MediaWiki's wikitext template language gained more features and grew more complicated. As early as 2009, MediaWiki developers began discussing the idea of embedding a real scripting language instead of continuing to make wikitext more complex.
Requirements for such a project included a strong sandbox and strict limitations on memory and CPU time usage, since it would be executing untrusted user code on production servers. It would need to be usable by shelling out to a standalone binary, with the ability to be run in-process via a PHP extension for better performance being a major benefit.
When development started in earnest circa 2011, four candidate languages were identified: Lua, JavaScript, PHP, or a hypothetical "WikiScript" language to be developed. Lua had several advantages:
- Small (170K standalone) and fast. The existence of LuaJIT was also considered a benefit.
- Designed for embedding, including easy hooks for CPU and memory limiting.
- Easy sandboxing, no internal globals.
- Detailed reference manual, including instructions on embedding.
The main disadvantage was that it wasn't known as widely as JavaScript.
JavaScript, in the form of the V8 engine at the time, had several disadvantages:
- Minimal documentation on embedding.
- Continued support for embedding unclear.
- No allocation hook.
- Huge standalone binary.
The Rhino engine was worse, as being written in Java it couldn't sanely be embedded in PHP at all. PHP itself was rejected since proper embedding and sandboxing would have been extremely difficult and pre-parsing would have been slow, and "WikiScript" would have been a much larger project in that it would have required developing an interpreter (or two) from scratch.
Thus, Lua was chosen, specifically version 5.1 that was available at the time, and this PHP extension was developed. The changes made to function environment handling in 5.2 have prevented a simple upgrade since, see phab:T178146 for details.