Как выполнить недоверяемый файл Lua в его собственной среде от API C

Я хочу выполнить недоверяемый .lua файл в его собственной среде путем вызова lua_setfenv () так, чтобы он не мог влиять ни на один мой код.

Документация для той функции, хотя только объясняет, как вызвать функцию, не, как выполнить файл.

В настоящее время для петляния я использую:

int error = luaL_loadfile(mState, path.c_str()) || lua_pcall(mState, 0, 0, 0);

Сделайте я должен назвать "dofile" lua функцией от API C с lua_setfenv, или есть ли более изящный способ сделать это?

6
задан Thomas Bonini 9 August 2010 в 21:20
поделиться

2 ответа

См. Обсуждение песочницы в Lua User's Wiki и более общую тему безопасности сценариев . Есть ряд тонких и не очень тонких проблем с подобными вещами. Это можно сделать, но защита от кода, такого как для i = 1,1e39 do end , требует большего, чем просто ограничение того, какие функции доступны для песочницы.

Общий метод заключается в создании функциональной среды для песочницы, в которой есть белый список разрешенных функций. В некоторых случаях этот список может даже быть пустым, но предоставление пользователю доступа к парам () , например, почти наверняка безвредно. На странице песочницы есть список системных функций с разбивкой по степени их безопасности в качестве удобного справочника для создания такого белого списка.

Затем вы используете lua_setfenv () , чтобы применить среду функций к пользовательскому скрипту, который вы загрузили (но еще не выполнили) с помощью lua_loadfile () или lua_loadstring () в зависимости от ситуации. С присоединенным окружением вы можете выполнить его с помощью lua_pcall () и друзей. Перед выполнением некоторые люди фактически сканировали загруженный байт-код на предмет операций, которые они не хотят разрешать. Это можно использовать для полного запрета циклов или записи в глобальные переменные.

Еще одно замечание: функции загрузки обычно загружают либо предварительно скомпилированный байт-код, либо текст Lua.Оказывается, будет намного безопаснее, если вы никогда не разрешите предварительно скомпилированный байт-код, поскольку было выявлено несколько способов заставить виртуальную машину работать неправильно, и все они зависят от ручной обработки недопустимого байт-кода. Поскольку файлы байт-кода начинаются с четко определенной последовательности байтов, которая не является простым текстом ASCII, все, что вам нужно сделать, это прочитать сценарий в строковом буфере, проверить отсутствие маркера и передать его только в lua_loadstring ( ) , если это не байт-код.

В течение многих лет в списке рассылки Lua-L было много дискуссий по этому поводу, так что поиск там также, вероятно, будет полезным.

9
ответ дан 8 December 2019 в 14:39
поделиться

luaL_loadfile () загрузит фрагмент, затем вызовет lua_setfenv () для установки таблицы среды, затем вызовет lua_pcall () для выполнения фрагмента. См. Недавний ответ судьи Мэйгардена на Вызов функций lua из файлов .lua с использованием дескрипторов?

2
ответ дан 8 December 2019 в 14:39
поделиться