LuaSandbox
LuaSandbox PHP 7 ve PHP 8 için, güvenilmeyen Lua 5.1 kodunun PHP içinden güvenli bir şekilde çalıştırılmasına izin veren bir uzantıdır; bu, genellikle bir Lua ikili dosyasına göndermekten ve süreçler arası iletişimi kullanmaktan daha hızlı olacaktır.
Kurulum
Ön paketli
LuaSandbox, Debian 10 ve Ubuntu 18.04 ve sonraki sürümlerde mevcuttur. Aşağıdaki komutla yükleyin:
apt install php-luasandbox -y
PECL
LuaSandbox artık önceden oluşturulmuş Windows DDL'leri de sağlayan PECL'de mevcuttur. Paket sayfamıza bakın. Önce, aşağıda "el kurulum" altında açıklandığı gibi doğru Lua 5.1 kitaplığını edinin. Sonra çalıştırın:
pecl install luasandbox
El kurulum
Gereksinimler
PHP ve Lua 5.1 için başlıkları ve kitaplık dosyalarını kurun.
- Ubuntu gibi Debian'dan türetilen Linux dağıtımları için:
apt install php-dev liblua5.1-0-dev -y
- CentOS/Redhat'tan türetilen Linux dağıtımları için:
yum install php-devel lua5.1 lua5.1-devel
- macOS için:
brew install lua
İndir
Kaynak kodunu git'ten uygun bir dizine indirin:
git init
git pull https://gerrit.wikimedia.org/r/mediawiki/php/luasandbox.git
Veya bir anlık görüntü indirin ve paketi açın.
Yapı
luasandbox
burada LuaSandbox Git deposunun klonlandığı dizindir.
cd luasandbox
phpize && ./configure && make && sudo make install
Ardından PHP yapılandırmasına uygun bir yere extension=luasandbox.so
ekleyin.
Örneğin, modern Debian'dan türetilen dağıtımlarda /etc/php/$version/mods-available
ile bir dosya eklersiniz (burada $version
, LuaSandbox'a uyduğunuz PHP sürümüdür) ve bunu etkinleştirmek için phpenmod
komutunu kullanırsınız.
LuaSandbox'ı MediaWiki gibi bir web uygulamasıyla kullanıyorsanız, uzantıyı yüklemek için web sunucunuzu veya PHP için php-fpm
yeniden başlatmanız gerekir.
Böyle bir yeniden yüklemeden sonra, LuaSandbox'ı phpinfo()
ve get_loaded_extensions()
(ve Scribunto yüklü MediaWiki için Special:Version) çıkışında görmelisiniz.
Örnekler
$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 50 * 1024 * 1024 );
$sandbox->setCPULimit( 10 );
// Lua ortamında bazı işlevleri kaydedin
function frobnosticate( $v ) {
return [ $v + 42 ];
}
$sandbox->registerLibrary( 'php', [
'frobnosticate' => 'frobnosticate',
'output' => function ( $string ) {
echo "$string\n";
},
'error' => function () {
throw new LuaSandboxRuntimeError( "Bir şey yanlış" );
}
] );
// PHP'ye ve Lua'ya yapılan geri aramalar dahil olmak üzere bazı Lua kodlarını yürütün
$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 tarafından atılan LuaSandboxRuntimeError istisnaları Lua içinde yakalanabilir
list( $ok, $message ) = $sandbox->loadString( 'return pcall( php.error )' )->call();
assert( !$ok );
assert( $message === 'Something is wrong' );
Belgelendirme
Belgelerimiz artık https://www.php.net/book.luasandbox adresindeki yukarı akış PHP kılavuzunda yaşıyor.
Kılavuzu değiştirmek istiyorsanız, GitHub'daki PHP kılavuz deposuna karşı bir çekme talebi gönderebilir veya uzantının Gerrit projesindeki LuaSandbox bölümünün aynasını değiştirebilirsiniz.
Standart Lua'dan farklılıklar
LuaSandbox, standart Lua 5.1'den bazı yönlerden farklı olan deneme tahtalı bir ortam sağlar.
Aşağıdaki işlevler ve paketler kullanılamaz:
- Doğrudan dosya sistemi erişimine izin verdikleri için
dofile()
,loadfile()
veio
paketi. Gerekirse, dosya sistemine erişim PHP geri çağrıları yoluyla yapılmalıdır. - Büyük ölçüde doğrudan dosya sistemi erişimine bağlı olduğundan,
require()
vemodule()
dahil olmak üzerepackage
. Bunun yerine Scribunto'da kullanılan gibi bir saf Lua yeniden yazma kullanılabilir. - Lua kodunun statik analizine izin vermek için
load()
veloadstring()
. - Standart çıkışa çıktığı için
print()
. Gerekirse, çıkış PHP geri çağrıları yoluyla yapılmalıdır. - İşlemin manipüle edilmesine ve diğer işlemlerin yürütülmesine izin verdiği için
os
paketinin çoğu.os.clock()
,os.date()
,os.difftime()
veos.time()
mevcut kalır.
debug
paketin çoğu, Lua durumunun ve meta verilerin deneme tahtasına bozabilecek şekillerde manipüle edilmesine izin verdiği için.debug.traceback()
kullanılabilir durumda kalır.
string.dump()
, çünkü dahili verileri açığa çıkarabilir.collectgarbage()
,gcinfo()
vecoroutine
paketi güvenlik açısından incelenmemiştir.
Aşağıdaki özellikler değiştirildi:
pcall()
vexpcall()
belirli hataları, özellikle zaman aşımı hatalarını yakalayamaz.tostring()
, işaretçi adreslerini içermez.- Özyineleme derinliğini sınırlamak ve bir zaman aşımını periyodik olarak kontrol etmek için
string.match()
yamalandı. math.random()
vemath.randomseed()
, PHP'ninrand()
ile durumu paylaşmayan sürümlerle değiştirilir.- Lua 5.2
__pairs
ve__ipairs
meta yöntemleripairs()
veipairs()
tarafından desteklenir.
Geçmiş
Yıllar geçtikçe, MediaWiki'nin vikimetin şablon dili daha fazla özellik kazandı ve daha karmaşık hâle geldi. 2009 gibi erken bir tarihte, MediaWiki geliştiricileri, vikimetni daha karmaşık hâle getirmeye devam etmek yerine gerçek bir betik dili yerleştirme fikrini tartışmaya başladılar.
Böyle bir proje için gereksinimler, üretim sunucularında güvenilmeyen kullanıcı kodunu çalıştıracağından, güçlü bir deneme tahtası ve bellek ve CPU zaman kullanımında katı sınırlamaları içeriyordu. Daha iyi performans için büyük bir fayda sağlamak için süreç içinde bir PHP uzantısı aracılığıyla çalıştırılabilme özelliği ile bağımsız bir ikili dosyaya bombardıman edilerek kullanılabilir olması gerekir.
Geliştirme 2011'de ciddi bir şekilde başladığında, dört aday dil belirlendi: Lua, JavaScript, PHP veya geliştirilecek varsayımsal bir "WikiScript" dili. Lua'nın birkaç avantajı vardı:
- Küçük (170K bağımsız) ve hızlı. LuaJIT'in varlığı da bir fayda olarak kabul edildi.
- CPU ve bellek sınırlaması için kolay kancalar dahil olmak üzere gömmek için tasarlanmıştır.
- Kolay deneme tahtası, dahili küresel yok.
- Gömme talimatları da dahil olmak üzere ayrıntılı kaynak kılavuzu.
Ana dezavantajı, JavaScript kadar yaygın olarak bilinmemesiydi.
O zamanlar V8 motoru biçimindeki JavaScript'in birkaç dezavantajı vardı:
- Gömmeyle ilgili minimum belgelendirme.
- Belirsiz gömme için devam eden destek.
- Ayırma kancası yok.
- Büyük bağımsız ikili dosya.
Rhino motoru daha kötüydü, Java ile yazıldığı için aklı başında PHP'ye yerleştirilemezdi. Doğru gömme ve deneme tahtası oluşturma son derece zor olacağından ve ön ayrıştırma yavaş olacağından PHP'nin kendisi reddedildi ve "WikiScript" sıfırdan bir (veya iki) yorumlayıcı geliştirmeyi gerektireceğinden çok daha büyük bir proje olacaktı.
Bu nedenle, Lua, özellikle o sırada mevcut olan 5.1 sürümü seçildi ve bu PHP uzantısı geliştirildi. 5.2'de ortam işleme işlevinde yapılan değişiklikler, o zamandan beri basit bir yükseltmeyi engelledi, ayrıntılar için phab:T178146 sayfasına bakın.